asp.net-mvc – MVC视图中的多个表单:ModelState应用于所有表单
在单一视图中遇到多种形式的麻烦.
假设我有以下viewmodel: public class ChangeBankAccountViewModel { public IEnumerable<BankInfo> BankInfos { get; set; } } public class BankInfo { [Required] public string BankAccount { get; set; } public long Id { get; set; } } 在我的视图模型中,我希望所有的BankInfos都可以在彼此之间显示,每个表单分开. 要实现这一点,我使用的是部分视图_EditBankInfo: @model BankInfo @using (Html.BeginForm()) { @Html.HiddenFor(m => m.InvoiceStructureId) @Html.TextBoxFor(m => m.IBANAccount) <button type="submit">Update this stuff</button> } 以及我的实际看法BankInfo: foreach(var info in Model.BankInfos) { Html.RenderPartial("_EditBankInfo",info); } 最后,这是我的2动作方法: [HttpGet] public ActionResult BankInfo() { return View(new ChangeBankAccountViewModel{BankInfos = new [] {new BankInfo...}); } [HttpPost] public ActionResult BankInfo(BankInfo model) { if(ModelState.IsValid) ModelState.Clear(); return BankInfo(); } 所有这些都是工作的hunky dory:验证工作顺利,发布模型得到认可和验证正确… 有什么办法容易防止这种情况发生吗? 我试过这样做,没有部分的意见,但螺丝的命名有点(他们是独一无二的,但服务器模型绑定将不会识别他们). 感谢任何答案. 解决方法
这有点棘手.这是如何解决的.首先将_EditBankInfo.cshtml部分移动到一个编辑器模板?/ Views / Shared / EditorTemplates / BankInfo.cshtml,看起来像这样(注意模板的名称和位置很重要,应该放在?/ Views / Shared / EditorTemplates,并命名为您的IEnumerable&T>集合属性中使用的类型名称,在您的情况下为BankInfo.cshtml):
@model BankInfo <div> @using (Html.BeginForm()) { <input type="hidden" name="model.prefix" value="@ViewData.TemplateInfo.HtmlFieldPrefix" /> @Html.HiddenFor(m => m.Id) @Html.TextBoxFor(m => m.BankAccount) <button type="submit">Update this stuff</button> } </div> 然后在你的主视图中摆脱foreach循环,并用一个简单的调用来替代EditorFor Helper: @model ChangeBankAccountViewModel @Html.EditorFor(x => x.BankInfos) 现在,对于BankInfos集合的每个元素,自定义编辑器模板将被渲染.与部分相反,编辑器模板尊重导航上下文,并将生成以下标记: <div> <form action="/" method="post"> <input type="hidden" name="model.prefix" value="BankInfos[0]" /> <input data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="BankInfos_0__Id" name="BankInfos[0].Id" type="hidden" value="1" /> <input data-val="true" data-val-required="The BankAccount field is required." id="BankInfos_0__BankAccount" name="BankInfos[0].BankAccount" type="text" value="account 1" /> <button type="submit">Update this stuff</button> </form> </div> <div> <form action="/" method="post"> <input type="hidden" name="model.prefix" value="BankInfos[1]" /> <input data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="BankInfos_1__Id" name="BankInfos[1].Id" type="hidden" value="2" /> <input data-val="true" data-val-required="The BankAccount field is required." id="BankInfos_1__BankAccount" name="BankInfos[1].BankAccount" type="text" value="account 2" /> <button type="submit">Update this stuff</button> </form> </div> ... 现在,由于每个字段都有一个特定的名称,因此在发布表单时不会再有冲突.注意我明确放置在每个窗体中的名为model.prefix的隐藏字段.这将由BankInfo类型的自定义模型binder使用: public class BankInfoModelBinder: DefaultModelBinder { public override object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { bindingContext.ModelName = controllerContext.HttpContext.Request.Form["model.prefix"]; return base.BindModel(controllerContext,bindingContext); } } 这将在您的Application_Start中注册: ModelBinders.Binders.Add(typeof(BankInfo),new BankInfoModelBinder()); 好的,现在我们很好去在您不再需要它的控制器动作中摆脱ModelState.Clear: [HttpGet] public ActionResult BankInfo() { var model = new ChangeBankAccountViewModel { // This is probably populated from some data store BankInfos = new [] { new BankInfo... },} return View(model); } [HttpPost] public ActionResult BankInfo(BankInfo model) { if(ModelState.IsValid) { // TODO: the model is valid => update its value into your data store // DO NOT CALL ModelState.Clear anymore. } return BankInfo(); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 玩玩asp.net 2.0的caching系列二 - RemoveOutputCacheItem
- ASP.NET MVC2模型验证失败,非美国日期格式
- asp.net-mvc-3 – 即使密码相同,比较验证器总是会启动
- asp.net-mvc – 使用RadioButtons的可空值布尔的MVC3 Edito
- asp.net-mvc – Html.BeginForm()工作正常,Html.BeginForm(
- 从ASP.NET MVC 2中排除授权操作
- ASP.NET核心:如何获取远程IP地址?
- asp.net-mvc – 网格中的kendoui ClientTemplate无法在asp.
- asp.net:部分类和继承
- ASP.NET WebAPI如何使用IIS存储我的用户身份验证状态?