小编典典

在Ajax调用之后,MVC3非侵入式验证不起作用

ajax

好的,这是交易,我已经看到一些有关此问题的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();
    }
}

阅读 277

收藏
2020-07-26

共1个答案

小编典典

$.validator.unobtrusive.parse("#frmAddItem");将工作。请注意,它必须位于通过ajax加载的局部文件中(在局部文件中的表单下方)

<form id="frmAddItem" method="POST" action="...">
    <!-- all the items -->
</form>
<script type="text/javascript">
    $.validator.unobtrusive.parse("#frmAddItem");
</script>
2020-07-26