好的,这是交易,我已经看到一些有关此问题的SO帖子,但是对我来说没有任何用处。
基本上,我有从局部视图中加载的选择下拉列表,我试图根据先前选择的下拉列表过滤每个后续下拉列表的内容。
如果仅将调用放在div容器中的部分视图中并加载页面,则从数据注释进行的验证就可以正常工作, 主要是Required属性 。
但是,如果我尝试通过AJAX加载与此处设置相同的部分,则必填验证无效,任何人都可以在此之后和KABOOM发布表单。
我发现有人说,在成功回调中,您需要让客户端验证程序重新解析该表单,而我正在尝试这样做,但似乎不起作用。
我有一个看起来像这样的视图…
@model Area51.Models.Workflow.AddReportableItemToBatchActionModel @{ ViewBag.Title = "Add Reportable Item to Batch"; Layout = "~/Views/Shared/_Layout.cshtml"; } <script type="text/javascript"> $(function () { var fadeDelay = 150; $(".jqDatePicker").datepicker({ dateFormat: 'm/d/yy', onSelect: function (date) { $("#categoryContainer").show(fadeDelay); } }); $('#Category').change(function () { RetrieveItemsForCategory(); $("#itemContainer").show(100); }); $('#Item').live('change', function () { RenderPartialForUOMByItem(); }); function RetrieveItemsForCategory() { var category = $("#Category :selected").val(); $.ajax({ type: "POST", url: '@Url.Action("RenderPartialForLocationItemsByCategory","BatchWorkflow")', data: 'category=' + category, success: function (result) { $("#itemContainer").html(result.toString()); $("#itemContainer").show(100); RebindValidation(); }, error: function (req, status, error) { alert("Sorry! Could not request items for your selection at this time."); } }); } function RenderPartialForUOMByItem() { var item = $("#Item :selected").val(); $.ajax({ type: "POST", url: '@Url.Action("RenderPartialForUOMByItem","BatchWorkflow")', data: "item=" + item, success: function (result) { $("#quantityContainer").html(result.toString()); $("#quantityContainer").show(100); RebindValidation(); }, error: function (req, status, error) { alert("Sorry! Could not request items for your selection at this time."); } }); } function RebindValidation() { alert("Rebinding Validation"); $.validator.unobtrusive.parse("#frmAddItem"); } }); // End OnLoad Event </script> <h3 class="pageHeader">Batch : @Model.BatchName</h3> <div align="center"> @{Html.BeginForm("AddItemToBatch", "BatchWorkflow", null, FormMethod.Post, new { id = "frmAddItem" });} @Html.ValidationSummary(true) <fieldset style="width:60%"> <legend>Add an Item to the Batch</legend> <div> <h3>Select Date Item was Added</h3> @Html.EditorFor(x => x.EventDate,null) <br /> </div> <div id="categoryContainer" style="display:none"> <hr /> <h3>Select an Inventory Category</h3> @Html.EditorFor(x => x.Category,null) <br /> </div> <div id="itemContainer" style="display:none"> @* @{Html.RenderAction("RenderPartialForLocationItemsByCategory", "BatchWorkflow", new { category = Model.Category });}*@ </div> <div id="quantityContainer" style="display:none"> @* @{Html.RenderAction("RenderPartialForUOMByItem", "BatchWorkflow", new { item = Model.Item });}*@ </div> <div id="reportingDataContainer" style="display:none"> <hr /> <h3>What quantity of the batch was affected by this addition?</h3> @Html.EditorFor(x => x.ConsumedWineQuantity) (Gallons) <br /> <hr /> <h3>What was the increase in Batch Volume as a result of this addition?</h3> @Html.EditorFor(x => x.ProducedWineQuantity) (Gallons) </div> <div style="display:block"> <div></div> <span><button type="button" id="btnCancel" class="linkButton" value="Cancel" onclick="location.href='@Url.Action("Home","Home",null)';">Cancel</button></span> <span><button type="submit" id="btnSubmit" class="linkButton" value="Add">Add Item</button></span> </div> </fieldset> @{ Html.EndForm(); } </div>
局部视图非常简单,基本上看起来像这样…
@model Area51.Models.Workflow.AddReportableItemToBatchActionModel <hr /> <h3>Select the Item to Add</h3> @Html.EditorFor(x => x.Item) <br />
同样,如果我只是RenderPartial,则验证工作正常,但是当我尝试通过ajax进行验证时,验证就会消失。将触发“重新绑定验证”警报,但是$ .validator.unobtrusive.parse(“#frmAddItem”); 似乎没有做任何事情。
有人可以帮我解决我所缺少的吗?这将不胜感激。
<=======================更新1 ========================= =====>
确定,我尝试添加$ .validator.unobtrusive.parse(“#frmAddItem”); 在文档准备好事件的部分视图的底部,它似乎也不起作用,基本上没有任何更改,我仍然可以提交表单。
我确实在这里找到了一个帖子:http ://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to- dynamic- content/提到当jqvalidation的MVC版本看到一个表单时验证规则绑定到它,它只是忽略.validator调用。我实现了这位先生使用的脚本扩展名,现在验证使用新的扩展名重新绑定到表单。我可以通过将html附加到表单并调用新的扩展名来进行测试,并将其重新绑定到新的文本框中。
但是,这仍不能完全解决问题。我使用Firebug来检查ajax调用返回的字段中的实际内容,并发现了一些非常奇怪的东西。
当我使用RenderPartial调用动作时,它会写出以下select:
<select id="Item" name="Item" data-val-required="The Item field is required." data-val-number="The field Item must be a number." data-val="true">
但是,当我对相同的完全相同的控制器动作进行ajax调用时,它会给我以下信息:
<select id="Item" name="Item">
我也尝试将脚本标签添加到部分视图中,但没有解决问题。出于某种原因,ajax调用会剥离不显眼的验证标签吗?
<=======================更新2 ======================== =====>
好的,现在发生了什么,我是下拉菜单的编辑器模板,它带有一个选择列表并将其转换为html select。我发现有一篇文章提到,要使数据验证属性写在编辑器模板上,您必须具有表单上下文。由于Html.RenderPartial是在表单中完成的,因此编辑器模板具有要使用的表单上下文。当我只是尝试通过ajax调用partial时,没有可用的表单上下文,并且没有抱怨它只是没有写出数据验证属性。在编辑器模板中为SelectListDropDown添加新的表单上下文可解决此问题。
@{ // fix to stop stupid crappy brad wilson mvc3 code from stripping the jq data valdiation attributes if (ViewContext.FormContext == null) { ViewContext.FormContext = new FormContext(); } }
$.validator.unobtrusive.parse("#frmAddItem");将工作。请注意,它必须位于通过ajax加载的局部文件中(在局部文件中的表单下方)
$.validator.unobtrusive.parse("#frmAddItem");
<form id="frmAddItem" method="POST" action="..."> <!-- all the items --> </form> <script type="text/javascript"> $.validator.unobtrusive.parse("#frmAddItem"); </script>