2011-09-20 46 views
11

我有一个非常简洁的表单,它将个人数据呈现为窗体中心的局部视图。我无法让客户端验证在此表单上工作。 我开始追查生成的html,并提出了在标准表单和局部视图上呈现的相同模型字段。MVC3 Razor部分视图渲染不包括数据验证属性

我注意到,在第一次调用@ html.partial时,输入元素被正确填充,以下情况仅在通过ajax请求重新加载partialview时发生。

首先我的部分视图的标题,这是在主页面上的Ajax.BeginForm。

@model MvcMPAPool.ViewModels.EventRegistration 
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")"   type="text/javascript"></script> 
<script type="text/javascript"> 
$(document).ready(function() 
{ 
    $(".phoneMask").mask("(999) 999-9999"); 
}); 
</script> 

@{ 
    var nPhn = 0; 
    var dTotal = 0.0D; 
    var ajaxOpts = new AjaxOptions{ HttpMethod="Post", UpdateTargetId="idRegistrationSummary", OnSuccess="PostOnSuccess" }; 
    Html.EnableClientValidation(true); 
    Html.EnableUnobtrusiveJavaScript(true); 
} 

下面是从局部视图剃刀标记:

@Html.ValidationMessageFor(model=>Model.Player.Person.Addresses[0].PostalCode) 
<table> 
    <tr> 
     <td style="width:200px;">City*</td> 
     <td>State</td> 
     <td>Zip/Postal Code</td> 
    </tr> 
    <tr> 
     <td>@Html.TextBoxFor(p=>Model.Player.Person.Addresses[0].CityName, new { style="width:200px;", maxlength=50 })</td> 
     <td> 
     @Html.DropDownListFor(p=> Model.Player.Person.Addresses[0].StateCode 
           , MPAUtils.GetStateList(Model.Player.Person.Addresses[0].StateCode))</td> 
     <td> 
     <div class="editor-field"> 
     @Html.TextBoxFor(p=>Model.Player.Person.Addresses[0].PostalCode, new { style="width:80px;", maxlength=10 }) 
     </div> 
     </td> 
    </tr> 
</table> 

下面是从局部视图呈现的字段:

 <td> 
     <div class="editor-field"> 
     <input id="Player_Person_Addresses_0__PostalCode" maxlength="10" name="Player.Person.Addresses[0].PostalCode" style="width:80px;" type="text" value="" /> 
     </div> 
     </td> 

这里是在渲染相同的模型字段标准视图:

 <div class="editor-field">    
      <input data-val="true" data-val-length="The field Postal/Zip Code must be a string with a maximum length of 10." data-val-length-max="10" data-val-required="Postal or Zip code must be provided!" id="Person_Addresses_0__PostalCode" maxlength="10" name="Person.Addresses[0].PostalCode" title="Postal/Zip Code is required" type="text" value="" />  
      <span class="field-validation-valid" data-valmsg-for="Person.Addresses[0].PostalCode" data-valmsg-replace="true"></span>   
     </div> 

请注意,局部视图呈现在输入元素上没有data-val-xxx属性。

这是正确的吗?我没有看到客户端验证如何在没有这些属性的情况下工作,或者我在这里丢失了一些基本的东西?

+0

参见['@using(Html.BeginSubForm())'答案](http://stackoverflow.com/a/8750181)为[ASP.NET MVC 3:生成不引人注目的验证时BeginForm是布局](http://stackoverflow.com/questions/4997269/asp-net-mvc-3-generate-unobtrusive-validation-when-beginform-is-on-the-layout)。 –

回答

18

为了创建不显眼的验证属性,必须存在FormContext。添加下面为您局部视图的顶部:

if (this.ViewContext.FormContext == null) 
{ 
    this.ViewContext.FormContext = new FormContext(); 
} 
+0

我检查了FormContext,它已经设置好了,所以一切都像原来那样工作。 –

+0

我将局部视图移到主视图中,验证工作正确。我认为这个表单可以被重写,并且保持这种方式,但我真的很想知道如何使这项工作。 –

+2

您的PartialView没有'@using Html.BeginForm()'或'@using Ajax.BeginForm()'声明,所以PartialView中没有'FormContext'。如果从View调用它,则将FormContext传递给它。如果从您的控制器中的某个操作调用它,则不传递FormContext。为了让它在这种情况下工作,PartialView必须实例化FormContext。这是通过在PartialView顶部的答案中添加代码块来完成的。 – counsellorben

9

如果你想在数据验证标签在那里,你需要在FormContext。因此,如果你是动态生成表单的部分,你需要在你的部分观点如下一行:

@{ if(ViewContext.FormContext == null) {ViewContext.FormContext = new FormContext(); }} 

然后你需要确保你重新绑定动态每次添加不显眼的验证/删除项目:

$("#form").removeData("validator"); 
$("#form").removeData("unobtrusiveValidation"); 
$.validator.unobtrusive.parse("#form"); 
+0

你的回答有很多帮助。非常感谢。 – bubuxu

+0

@dazbradbury在哪里包括这些?请告诉我我有同样的问题 –