HTTPPost 上的 MVC5 ViewModel 属性为空
MVC5 ViewModel properties null on HTTPPost
我知道,以前有人问过这个问题,但我还没有找到答案,而且我的示例似乎比大多数示例简单得多。我确保模型数据在表单内,并确保 Post 操作与 Get 操作相匹配;没有日期格式问题;并且我有类似的视图和控制器,我已经比较过它们工作正常。此示例使用常规路由,但我也尝试过属性路由,但行为没有变化。我什至删除了 EditorFor ReportName 并将其放在 HiddenFor 中。隐藏的 ReportID 始终填充且正确,ReportName 和 ReportAbbr 始终为空。 :(
首先,这是我的视图模型:
namespace Core.AdminData
{
[System.Runtime.Serialization.DataContract(Name = "MyReport")]
public class MyReport
{
[System.Runtime.Serialization.DataMember(Name = "ReportID", Order = 0)]
public int ReportID { get; set; }
[System.Runtime.Serialization.DataMember(Name = "ReportName", Order = 1)]
[Display(Name = "Name")]
[Required(ErrorMessage = "Name Required")]
public string ReportName { get; private set; }
[System.Runtime.Serialization.DataMember(Name = "ReportAbbr", Order = 2)]
[Display(Name = "Abbreviation")]
[Required(ErrorMessage = "Abbreviation Required")]
public string ReportAbbr { get; private set; }
public MyReport()
{
;
}
}
}
这是我的控制器:
public class ReportsController : Controller
{
[HttpGet]
public ActionResult TrendEdit(int id)
{
using (Client client = new Client(ConfigHelper.Protocol(), ConfigHelper.Host(), ConfigHelper.Port()))
{
MyReport rpt = null;
try
{
rpt = client.GetReport(id);
if (rpt == null)
{
TempData["ErrorText"] = "Report does not exist";
return this.RedirectToAction("List");
}
}
catch (Exception exc)
{
TempData["ErrorText"] = exc.Message;
return this.RedirectToAction("List");
}
return View(rpt);
}
}
[HttpPost]
public ActionResult TrendEdit(MyReport report)
{
using (Client client = new Client(ConfigHelper.Protocol(), ConfigHelper.Host(), ConfigHelper.Port()))
{
try
{
if (!this.ModelState.IsValid || client.UpdateReport(report).StatusCode != SSStatus.Success)
{
ViewBag.ErrorText = "An error occurred. Please contact your web administrator for assistance.";
return View(report);
}
}
catch (Exception exc)
{
ViewBag.ErrorText = exc.Message;
return View(report);
}
return this.RedirectToAction("List");
}
}
}
最后,这是我的观点:
@using Core.AdminData
@model MyReport
@{
ViewBag.Title = "Edit Report";
Layout = "~/Views/Shared/_ContentLayout.cshtml";
}
<div class="panel panel-default">
<div class="panel-heading hidden-xs">
<h4>Edit Report</h4>
</div>
@using (Html.BeginForm())
{
@Html.HiddenFor(model => model.ReportID)
<div class="container-fluid panel-body">
<div class="row">
<div class="col-xs-12 message-error">@ViewBag.ErrorText</div>
</div>
<div class="row">
<div class="col-xs-4 col-md-3 custom-label">
@Html.LabelFor(model => model.ReportName)
</div>
<div class="col-xs-8 col-md-9 custom-field">
@Html.EditorFor(model => model.ReportName)
</div>
</div>
<div class="row">
<div class="col-xs-offset-4 col-xs-8 col-md-offset-3 col-md-9 message-error">
@Html.ValidationMessageFor(model => model.ReportName)
</div>
</div>
<div class="row">
<div class="col-xs-4 col-md-3 custom-label">
@Html.LabelFor(model => model.ReportAbbr)
</div>
<div class="col-xs-8 col-md-9 custom-field">
@Html.EditorFor(model => model.ReportAbbr)
</div>
</div>
<div class="row">
<div class="col-xs-offset-4 col-xs-8 col-md-offset-3 col-md-9 message-error">
@Html.ValidationMessageFor(model => model.ReportAbbr)
</div>
</div>
<div class="row">
<div class="col-xs-4 col-md-3 text-right">
<input type="submit" value="Save" class="btn btn-default btn-sm" />
</div>
</div>
</div>
}
</div>
如果我遗漏了任何有用的代码,请告诉我。我希望这是显而易见的事情。我宁愿有一个 "Duh" 的时刻,也不愿继续与这段代码作斗争。 ;) TIA!
您的 ReportName
和 ReportAbbr
属性具有私有设置器,因此 DefaultModelBinder
无法设置值。将它们更改为具有 public 个设置器
public string ReportName { get; set; }
public string ReportAbbr { get; set; }
我知道,以前有人问过这个问题,但我还没有找到答案,而且我的示例似乎比大多数示例简单得多。我确保模型数据在表单内,并确保 Post 操作与 Get 操作相匹配;没有日期格式问题;并且我有类似的视图和控制器,我已经比较过它们工作正常。此示例使用常规路由,但我也尝试过属性路由,但行为没有变化。我什至删除了 EditorFor ReportName 并将其放在 HiddenFor 中。隐藏的 ReportID 始终填充且正确,ReportName 和 ReportAbbr 始终为空。 :(
首先,这是我的视图模型:
namespace Core.AdminData
{
[System.Runtime.Serialization.DataContract(Name = "MyReport")]
public class MyReport
{
[System.Runtime.Serialization.DataMember(Name = "ReportID", Order = 0)]
public int ReportID { get; set; }
[System.Runtime.Serialization.DataMember(Name = "ReportName", Order = 1)]
[Display(Name = "Name")]
[Required(ErrorMessage = "Name Required")]
public string ReportName { get; private set; }
[System.Runtime.Serialization.DataMember(Name = "ReportAbbr", Order = 2)]
[Display(Name = "Abbreviation")]
[Required(ErrorMessage = "Abbreviation Required")]
public string ReportAbbr { get; private set; }
public MyReport()
{
;
}
}
}
这是我的控制器:
public class ReportsController : Controller
{
[HttpGet]
public ActionResult TrendEdit(int id)
{
using (Client client = new Client(ConfigHelper.Protocol(), ConfigHelper.Host(), ConfigHelper.Port()))
{
MyReport rpt = null;
try
{
rpt = client.GetReport(id);
if (rpt == null)
{
TempData["ErrorText"] = "Report does not exist";
return this.RedirectToAction("List");
}
}
catch (Exception exc)
{
TempData["ErrorText"] = exc.Message;
return this.RedirectToAction("List");
}
return View(rpt);
}
}
[HttpPost]
public ActionResult TrendEdit(MyReport report)
{
using (Client client = new Client(ConfigHelper.Protocol(), ConfigHelper.Host(), ConfigHelper.Port()))
{
try
{
if (!this.ModelState.IsValid || client.UpdateReport(report).StatusCode != SSStatus.Success)
{
ViewBag.ErrorText = "An error occurred. Please contact your web administrator for assistance.";
return View(report);
}
}
catch (Exception exc)
{
ViewBag.ErrorText = exc.Message;
return View(report);
}
return this.RedirectToAction("List");
}
}
}
最后,这是我的观点:
@using Core.AdminData
@model MyReport
@{
ViewBag.Title = "Edit Report";
Layout = "~/Views/Shared/_ContentLayout.cshtml";
}
<div class="panel panel-default">
<div class="panel-heading hidden-xs">
<h4>Edit Report</h4>
</div>
@using (Html.BeginForm())
{
@Html.HiddenFor(model => model.ReportID)
<div class="container-fluid panel-body">
<div class="row">
<div class="col-xs-12 message-error">@ViewBag.ErrorText</div>
</div>
<div class="row">
<div class="col-xs-4 col-md-3 custom-label">
@Html.LabelFor(model => model.ReportName)
</div>
<div class="col-xs-8 col-md-9 custom-field">
@Html.EditorFor(model => model.ReportName)
</div>
</div>
<div class="row">
<div class="col-xs-offset-4 col-xs-8 col-md-offset-3 col-md-9 message-error">
@Html.ValidationMessageFor(model => model.ReportName)
</div>
</div>
<div class="row">
<div class="col-xs-4 col-md-3 custom-label">
@Html.LabelFor(model => model.ReportAbbr)
</div>
<div class="col-xs-8 col-md-9 custom-field">
@Html.EditorFor(model => model.ReportAbbr)
</div>
</div>
<div class="row">
<div class="col-xs-offset-4 col-xs-8 col-md-offset-3 col-md-9 message-error">
@Html.ValidationMessageFor(model => model.ReportAbbr)
</div>
</div>
<div class="row">
<div class="col-xs-4 col-md-3 text-right">
<input type="submit" value="Save" class="btn btn-default btn-sm" />
</div>
</div>
</div>
}
</div>
如果我遗漏了任何有用的代码,请告诉我。我希望这是显而易见的事情。我宁愿有一个 "Duh" 的时刻,也不愿继续与这段代码作斗争。 ;) TIA!
您的 ReportName
和 ReportAbbr
属性具有私有设置器,因此 DefaultModelBinder
无法设置值。将它们更改为具有 public 个设置器
public string ReportName { get; set; }
public string ReportAbbr { get; set; }