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 – 嵌套的Repeater和SqlDataSource参数
- asp.net-mvc – MVC 3部分页面(Razor)和MVC 3视图页面与布局
- 远程服务器返回错误:(401)未经授权.在ASP.NET中使用CSOM
- 使用ASP.NET Web API进行OAuth Facebook身份验证
- asp.net – 如何添加一个空的第一个条目做一个?
- 有没有替代ASP.NET的C#web开发?
- asp.net-mvc – 保持viewdata在RedirectToAction
- 使用Asp.net Web API时,使用DataContract和DataMember属性有
- asp.net-mvc-3 – 找不到布局页面“{path}”
- asp.net-mvc – 如何设置html.EditorFor helper的大小?
- 如何使用AutoMapper将多个OBJECTS映射到一个对象
- 我可以在.NET中设置IIS MIME类型吗?
- asp.net-core – 对Post请求的两次调用:使用htt
- asp.net – GridView中的TemplateField标题
- asp.net-mvc-3 – 如何增加会话超时MVC 3
- asp.net-mvc – 使用文件扩展名创建ActionResult
- asp.net – Web.config允许特定用户的位置访问
- ASP.NET对txt文件相关操作(读
- asp.net-mvc – 使用ViewModels和对System.Web.M
- 在ASP.NET MVC中模拟User.Identity
