混淆了我的两个模型,Post 请求中的空引用(ASP.NET MVC)
Mixed up my Two Models, Null Reference in Post Request (ASP.NET MVC)
我正在尝试提供一个 table,其中包含数据库中的行列表,以及供用户添加额外数据库行的小表单选项。我制作了两个模型,以便同时保存 table 行和捕获表单。 table 模型没有问题,只有表单模型有问题。
所以我确信问题出在我的控制器上;我是 MVC 的新手,这是我第一次在同一个 VM 中看到两个模型......我一直在来回做一些小改动,但我的控制器中一直出现空引用错误。
虚拟机:
namespace User.ViewModel
{
public class UploadDocumentTemplatesViewModel
{
public string TemplateName { get; set; }
public string Comments { get; set; }
}
public class TemplateModel
{
public UploadDocumentTemplatesViewModel NewTemplate { get; set; }
public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
}
}
查看(UploadDocumentTemplates.cshtml):
@using (Html.BeginForm("AddNewTemplate", "User", FormMethod.Post, new { enctype = "multipart/form-data", id = "NewTemplateForm"}))
{
@Html.AntiForgeryToken()
<div>
<input type="text" class="form-control" rows="5" id="TemplateName" value="@Model.NewTemplate.TemplateName">
<label for="comments">Comments:</label>
<textarea class="form-control" rows="5" id="comments" name="@Model.NewTemplate.Comments"></textarea>
<button id="AddTemplate" onclick="AddNewTemplate()" name="Add Template">Add Template</button>
</div>
}
<table>
<tbody>
@{ foreach (var template in Model.Templates)
{
<tr id="tr_@template.DocumentTemplateId">
<td>@template.TemplateName</td>
<td>@template.Comments </td>
<td>@template.IsActive </td>
}
<script>
function AddNewTemplate() {
$("#NewTemplateForm").submit();
}
</script>
控制器:
public class UserController : Controller
{
public ActionResult UploadDocumentTemplates()
{
var model = entity.DocumentTemplates.Select(x => new UploadDocumentTemplatesViewModel()
{
DocumentTemplateId = x.DocumentTemplateId,
TemplateName = x.TemplateName,
Comments = x.Comments,
});
var _obj = new TemplateModel();
var templatelist = _entities.GetTemplates();
_obj.Templates = new List<UploadDocumentTemplatesViewModel>();
foreach (var template in templatelist)
{
_obj.Templates.Add(new UploadDocumentTemplatesViewModel()
{
TemplateName = template.TemplateName,
Comments = template.Comments,
});
}
_obj.NewTemplate = new UploadDocumentTemplatesViewModel();
return View(_obj);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddNewTemplate(TemplateModel vModel)
{
var template = new DocumentTemplates();
template.TemplateName = vModel.NewTemplate.TemplateName;
template.Comments = vModel.NewTemplate.Comments;
entity.DocumentTemplates.Add(template);
entity.SaveChanges();
return View("~/User/UploadDocumentTemplates.cshtml", vModel);
}
}
我在控制器的 Post 方法中的这一行遇到了一个空引用:
template.TemplateName = vModel.NewTemplate.TemplateName;
vModel.NewTemplate.TemplateName 为空。谁能帮我解决这个问题?
非常感谢!
解决方案:
在 Andy 的帮助下,NRE 确实得到了修复(参见答案)。在我用我在表单中使用的字段填充新 VM 后,我的进一步问题得到解决。
namespace Example.Areas.ViewModel
{
public class UploadDocumentTemplatesViewModel
{
public long DocumentTemplateId { get; set; }
public string TemplateName { get; set; }
public string Comments { get; set; }
}
public class TemplateModel
{
public string TemplateName { get; set; }
public string Comments { get; set; }
public HttpPostedFileBase TemplateFile { get; set; }
public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
}
}
在控制器中,我填充了 TemplateModel 并将其发送到视图:
public ActionResult UploadDocumentTemplates()
{
var templateList = Repository.GetTemplates();
var _obj = new TemplateModel
{
Templates = templateList.Select(x => new UploadDocumentTemplatesViewModel()
{
DocumentTemplateId = x.DocumentTemplateId,
TemplateName = x.TemplateName,
Comments = x.Comments
}).ToList()
};
return View(_obj);
}
然后我将@using Example.Areas.ViewModel.TemplateModel 放在我的视图上,并使用 Model.Templates 作为 table,并在表单中使用 Model.TemplateName 和 Model.Comments。
在您命中空引用的行中添加断点并检查 vModel.NewTemplate
是否具有有效实例。
您可以在TemplateModel
class中添加构造函数来创建UploadDocumentTemplatesViewModel()
的新实例
namespace User.ViewModel
{
public class UploadDocumentTemplatesViewModel
{
public string TemplateName { get; set; }
public string Comments { get; set; }
}
public class TemplateModel
{
public TemplateModel()
{
NewTemplate = new UploadDocumentTemplatesViewModel();
}
public UploadDocumentTemplatesViewModel NewTemplate { get; set; }
public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
}
}
或
实例化后创建一个实例template
:
var template = new DocumentTemplates();
template.NewTemplate = new UploadDocumentTemplatesViewModel();
我正在尝试提供一个 table,其中包含数据库中的行列表,以及供用户添加额外数据库行的小表单选项。我制作了两个模型,以便同时保存 table 行和捕获表单。 table 模型没有问题,只有表单模型有问题。
所以我确信问题出在我的控制器上;我是 MVC 的新手,这是我第一次在同一个 VM 中看到两个模型......我一直在来回做一些小改动,但我的控制器中一直出现空引用错误。
虚拟机:
namespace User.ViewModel
{
public class UploadDocumentTemplatesViewModel
{
public string TemplateName { get; set; }
public string Comments { get; set; }
}
public class TemplateModel
{
public UploadDocumentTemplatesViewModel NewTemplate { get; set; }
public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
}
}
查看(UploadDocumentTemplates.cshtml):
@using (Html.BeginForm("AddNewTemplate", "User", FormMethod.Post, new { enctype = "multipart/form-data", id = "NewTemplateForm"}))
{
@Html.AntiForgeryToken()
<div>
<input type="text" class="form-control" rows="5" id="TemplateName" value="@Model.NewTemplate.TemplateName">
<label for="comments">Comments:</label>
<textarea class="form-control" rows="5" id="comments" name="@Model.NewTemplate.Comments"></textarea>
<button id="AddTemplate" onclick="AddNewTemplate()" name="Add Template">Add Template</button>
</div>
}
<table>
<tbody>
@{ foreach (var template in Model.Templates)
{
<tr id="tr_@template.DocumentTemplateId">
<td>@template.TemplateName</td>
<td>@template.Comments </td>
<td>@template.IsActive </td>
}
<script>
function AddNewTemplate() {
$("#NewTemplateForm").submit();
}
</script>
控制器:
public class UserController : Controller
{
public ActionResult UploadDocumentTemplates()
{
var model = entity.DocumentTemplates.Select(x => new UploadDocumentTemplatesViewModel()
{
DocumentTemplateId = x.DocumentTemplateId,
TemplateName = x.TemplateName,
Comments = x.Comments,
});
var _obj = new TemplateModel();
var templatelist = _entities.GetTemplates();
_obj.Templates = new List<UploadDocumentTemplatesViewModel>();
foreach (var template in templatelist)
{
_obj.Templates.Add(new UploadDocumentTemplatesViewModel()
{
TemplateName = template.TemplateName,
Comments = template.Comments,
});
}
_obj.NewTemplate = new UploadDocumentTemplatesViewModel();
return View(_obj);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddNewTemplate(TemplateModel vModel)
{
var template = new DocumentTemplates();
template.TemplateName = vModel.NewTemplate.TemplateName;
template.Comments = vModel.NewTemplate.Comments;
entity.DocumentTemplates.Add(template);
entity.SaveChanges();
return View("~/User/UploadDocumentTemplates.cshtml", vModel);
}
}
我在控制器的 Post 方法中的这一行遇到了一个空引用:
template.TemplateName = vModel.NewTemplate.TemplateName;
vModel.NewTemplate.TemplateName 为空。谁能帮我解决这个问题?
非常感谢!
解决方案:
在 Andy 的帮助下,NRE 确实得到了修复(参见答案)。在我用我在表单中使用的字段填充新 VM 后,我的进一步问题得到解决。
namespace Example.Areas.ViewModel
{
public class UploadDocumentTemplatesViewModel
{
public long DocumentTemplateId { get; set; }
public string TemplateName { get; set; }
public string Comments { get; set; }
}
public class TemplateModel
{
public string TemplateName { get; set; }
public string Comments { get; set; }
public HttpPostedFileBase TemplateFile { get; set; }
public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
}
}
在控制器中,我填充了 TemplateModel 并将其发送到视图:
public ActionResult UploadDocumentTemplates()
{
var templateList = Repository.GetTemplates();
var _obj = new TemplateModel
{
Templates = templateList.Select(x => new UploadDocumentTemplatesViewModel()
{
DocumentTemplateId = x.DocumentTemplateId,
TemplateName = x.TemplateName,
Comments = x.Comments
}).ToList()
};
return View(_obj);
}
然后我将@using Example.Areas.ViewModel.TemplateModel 放在我的视图上,并使用 Model.Templates 作为 table,并在表单中使用 Model.TemplateName 和 Model.Comments。
在您命中空引用的行中添加断点并检查 vModel.NewTemplate
是否具有有效实例。
您可以在TemplateModel
class中添加构造函数来创建UploadDocumentTemplatesViewModel()
namespace User.ViewModel
{
public class UploadDocumentTemplatesViewModel
{
public string TemplateName { get; set; }
public string Comments { get; set; }
}
public class TemplateModel
{
public TemplateModel()
{
NewTemplate = new UploadDocumentTemplatesViewModel();
}
public UploadDocumentTemplatesViewModel NewTemplate { get; set; }
public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
}
}
或
实例化后创建一个实例template
:
var template = new DocumentTemplates();
template.NewTemplate = new UploadDocumentTemplatesViewModel();