ASP.NET MVC - POST ViewModel 中的空对象
ASP.NET MVC - Null Object in ViewModel on POST
在 ActionController 的 POST 上,我收到了很棒的 ole' 对象引用未设置为对象的实例 错误。
基本上我需要将 userRequest 的 ID 与 requestResponse 一起保存。 (这里是外键)
这是代码。
ViewModel:
public class RequestResponseViewModel
{
public Models.Request userRequest { get; set; }
public Models.RequestResponse requestResponse { get; set; }
}
查看: 在调试中 model.userRequest.ID
中有值
@model UserRequests.ViewModels.RequestResponseViewModel
@{
ViewBag.Title = "Create";
}
<h2>Admin Response to Request</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.requestResponse.Response,
htmlAttributes: new { @class = "control-label col-md-1" })
<div class="col-md-10">
@Html.TextAreaFor(model => model.requestResponse.Response, new {
@class = "form-control", @rows = 5 })
@Html.ValidationMessageFor(model =>
model.requestResponse.Response, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.userRequest.ID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.DisplayFor(model => model.userRequest.ID)
@Html.ValidationMessageFor(model => model.userRequest.ID, "", new { @class = "text-danger" })
</div>
@Html.LabelFor(model => model.requestResponse.Author, htmlAttributes: new { @class = "control-label col-md-1" })
<div class="col-md-3">
@Html.EditorFor(model => model.requestResponse.Author, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.requestResponse.Author, "", new { @class = "text-danger" })
</div>
@Html.LabelFor(model => model.requestResponse.CreateDate, htmlAttributes: new { @class = "control-label col-md-1" })
<div class="col-md-3">
<h5>@DateTime.Now</h5>
@Html.ValidationMessageFor(model => model.requestResponse.CreateDate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-1">
<button type="reset" class="btn btn-default">Cancel</button>
<input type="submit" value="Create" class="btn btn-success" />
</div>
</div>
</div>
<hr />
<h3 class="text-success">Original Request</h3>
<div class="row">
<div class="col-md-10">
<h4>@Html.DisplayFor(model => model.userRequest.Title)</h4>
</div>
</div>
<div class="row">
<div class="col-md-10">
<h4>@Html.DisplayFor(model => model.userRequest.Description)</h4>
</div>
</div>
}
<div>
@Html.ActionLink("Back to Browse", "Browse","Change")
</div>
获取操作结果:
public ActionResult Create(int id)
{
UserRequestContextDataContext db = new UserRequestContextDataContext();
var request = (from m in db.Requests
where m.ID == id
select new Models.Request()
{
ID = m.ID,
Title = m.Title,
Description = m.Description,
BusinessUnit = m.BusinessUnit,
Author = m.Author,
ModuleName = m.MenuItem,
RequestStatus = 2,
SubmitDate = m.SubmitDate,
Type = m.Type,
UrgencyNum = m.UrgencyLevel
}).FirstOrDefault();
var reqResponse = new Models.RequestResponse();
var viewModel = new RequestResponseViewModel
{
userRequest = request,
requestResponse = reqResponse
};
return View(viewModel);
}
这里的"viewModel"有我需要的一切。它丢失在 ActionResults 之间的某处..
最后 Post ActionResult:
[HttpPost]
public ActionResult Create(RequestResponseViewModel _requestResponseViewModel)
{
try
{
if (ModelState.IsValid)
{
using (UserRequestContextDataContext db = new UserRequestContextDataContext())
{
RequestResponse reqRes = new RequestResponse();
reqRes.Response = _requestResponseViewModel.requestResponse.Response.ToString();
reqRes.RequestID = _requestResponseViewModel.userRequest.ID;
reqRes.Author = _requestResponseViewModel.requestResponse.Author.ToString();
reqRes.CreateDate = DateTime.Now;
db.RequestResponses.InsertOnSubmit(reqRes);
db.SubmitChanges();
}
}
return RedirectToAction("Browse","Change");
}
catch (Exception ex)
{
return View("Error", new HandleErrorInfo(ex, "Change", "Create"));
}
}
使用调试模式,userRequest 对象在 POST 方法的视图模型参数中为 NULL,但 requestResponse 为 FINE 并按应有的方式填充。
对此进行搜索,似乎大部分问题都与视图模型中的命名约定有关,但我已确保那里没有差异。
如果有更清晰的方法来完成此工作流程,请提及。
@Html.DisplayFor
不会创建 HTML 输入元素,而是创建一个简单的字符串文字(对于大多数类型,文档中列出了一些例外情况:https://msdn.microsoft.com/en-us/library/ee407420(v=vs.118).aspx#Anchor_1)。
因此,当您按下提交时,您的浏览器不会将 ID 发送回服务器,因为它只发送表单数据(例如来自输入、textare、select 字段的数据)。使用浏览器开发人员工具 (F12),您可以检查实际发送到服务器的内容。
您可以使用@Html.HiddenFor(model => model.userRequest.ID)
添加隐藏输入框,或使用ID的自定义显示模板自动添加隐藏输入框。您可以进一步使用 UIHint
属性自动 select 显示模板。这两种方法都有详尽的记录(例如 http://www.codeguru.com/csharp/.net/net_asp/mvc/using-display-templates-and-editor-templates-in-asp.net-mvc.htm)。
对象在 POST 中可能为 NULL 的另一个原因是忘记添加设置器 { get;放; } 在你的视图模型中:
public 订单订单; --> 缺少 { 得到;放; }
public class OrderViewModel
{
public Orders orders { get; set; }
public List<VendorJobTitleView> Jobs { get; set; }
public List<ManagerView> Managers { get; set; }
}
在 ActionController 的 POST 上,我收到了很棒的 ole' 对象引用未设置为对象的实例 错误。
基本上我需要将 userRequest 的 ID 与 requestResponse 一起保存。 (这里是外键)
这是代码。
ViewModel:
public class RequestResponseViewModel
{
public Models.Request userRequest { get; set; }
public Models.RequestResponse requestResponse { get; set; }
}
查看: 在调试中 model.userRequest.ID
中有值 @model UserRequests.ViewModels.RequestResponseViewModel
@{
ViewBag.Title = "Create";
}
<h2>Admin Response to Request</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.requestResponse.Response,
htmlAttributes: new { @class = "control-label col-md-1" })
<div class="col-md-10">
@Html.TextAreaFor(model => model.requestResponse.Response, new {
@class = "form-control", @rows = 5 })
@Html.ValidationMessageFor(model =>
model.requestResponse.Response, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.userRequest.ID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.DisplayFor(model => model.userRequest.ID)
@Html.ValidationMessageFor(model => model.userRequest.ID, "", new { @class = "text-danger" })
</div>
@Html.LabelFor(model => model.requestResponse.Author, htmlAttributes: new { @class = "control-label col-md-1" })
<div class="col-md-3">
@Html.EditorFor(model => model.requestResponse.Author, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.requestResponse.Author, "", new { @class = "text-danger" })
</div>
@Html.LabelFor(model => model.requestResponse.CreateDate, htmlAttributes: new { @class = "control-label col-md-1" })
<div class="col-md-3">
<h5>@DateTime.Now</h5>
@Html.ValidationMessageFor(model => model.requestResponse.CreateDate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-1">
<button type="reset" class="btn btn-default">Cancel</button>
<input type="submit" value="Create" class="btn btn-success" />
</div>
</div>
</div>
<hr />
<h3 class="text-success">Original Request</h3>
<div class="row">
<div class="col-md-10">
<h4>@Html.DisplayFor(model => model.userRequest.Title)</h4>
</div>
</div>
<div class="row">
<div class="col-md-10">
<h4>@Html.DisplayFor(model => model.userRequest.Description)</h4>
</div>
</div>
}
<div>
@Html.ActionLink("Back to Browse", "Browse","Change")
</div>
获取操作结果:
public ActionResult Create(int id)
{
UserRequestContextDataContext db = new UserRequestContextDataContext();
var request = (from m in db.Requests
where m.ID == id
select new Models.Request()
{
ID = m.ID,
Title = m.Title,
Description = m.Description,
BusinessUnit = m.BusinessUnit,
Author = m.Author,
ModuleName = m.MenuItem,
RequestStatus = 2,
SubmitDate = m.SubmitDate,
Type = m.Type,
UrgencyNum = m.UrgencyLevel
}).FirstOrDefault();
var reqResponse = new Models.RequestResponse();
var viewModel = new RequestResponseViewModel
{
userRequest = request,
requestResponse = reqResponse
};
return View(viewModel);
}
这里的"viewModel"有我需要的一切。它丢失在 ActionResults 之间的某处..
最后 Post ActionResult:
[HttpPost]
public ActionResult Create(RequestResponseViewModel _requestResponseViewModel)
{
try
{
if (ModelState.IsValid)
{
using (UserRequestContextDataContext db = new UserRequestContextDataContext())
{
RequestResponse reqRes = new RequestResponse();
reqRes.Response = _requestResponseViewModel.requestResponse.Response.ToString();
reqRes.RequestID = _requestResponseViewModel.userRequest.ID;
reqRes.Author = _requestResponseViewModel.requestResponse.Author.ToString();
reqRes.CreateDate = DateTime.Now;
db.RequestResponses.InsertOnSubmit(reqRes);
db.SubmitChanges();
}
}
return RedirectToAction("Browse","Change");
}
catch (Exception ex)
{
return View("Error", new HandleErrorInfo(ex, "Change", "Create"));
}
}
使用调试模式,userRequest 对象在 POST 方法的视图模型参数中为 NULL,但 requestResponse 为 FINE 并按应有的方式填充。
对此进行搜索,似乎大部分问题都与视图模型中的命名约定有关,但我已确保那里没有差异。
如果有更清晰的方法来完成此工作流程,请提及。
@Html.DisplayFor
不会创建 HTML 输入元素,而是创建一个简单的字符串文字(对于大多数类型,文档中列出了一些例外情况:https://msdn.microsoft.com/en-us/library/ee407420(v=vs.118).aspx#Anchor_1)。
因此,当您按下提交时,您的浏览器不会将 ID 发送回服务器,因为它只发送表单数据(例如来自输入、textare、select 字段的数据)。使用浏览器开发人员工具 (F12),您可以检查实际发送到服务器的内容。
您可以使用@Html.HiddenFor(model => model.userRequest.ID)
添加隐藏输入框,或使用ID的自定义显示模板自动添加隐藏输入框。您可以进一步使用 UIHint
属性自动 select 显示模板。这两种方法都有详尽的记录(例如 http://www.codeguru.com/csharp/.net/net_asp/mvc/using-display-templates-and-editor-templates-in-asp.net-mvc.htm)。
对象在 POST 中可能为 NULL 的另一个原因是忘记添加设置器 { get;放; } 在你的视图模型中:
public 订单订单; --> 缺少 { 得到;放; }
public class OrderViewModel
{
public Orders orders { get; set; }
public List<VendorJobTitleView> Jobs { get; set; }
public List<ManagerView> Managers { get; set; }
}