繁体   English   中英

JavaScript填充的DropDown在ModelState中无效

[英]JavaScript populated DropDown not valid in ModelState

我在做什么:我有3个组合框。 前两个框中的选择确定第三个框中的列表。 每当在前两个框中的任何一个中进行选择时,我都会运行一些jQuery,调用$ .ajax来获取第三个框中的列表。 第三个框是我的“项目描述”框。

问题: jquery ajax调用有效。 当我在前两个框中选择值时,“项目描述”将加载到第三个框中。 但是,当我尝试提交表单时,ModelState.IsValid = false,并且ModelState错误消息显示“需要项说明”。

这来自我模型的元数据:

[Required(ErrorMessage = "Item Description is required.")]
public int ItemDescriptionID { get; set; }

我不希望用户不选择说明就可以提交表单。 我可以在提交后进行验证,但我希望MVC可以进行验证。

这是我正在使用的JavaScript ...

function getModels() {
    catId = $('#ItemModel_ItemCategoryID').val();
    manuId = $('#ItemModel_ItemManufacturerID').val();

    // remove all of the current options from the list
    $('#ItemDescriptionID').empty();

    // send request for model list based on category and manufacturer
    var jqxhr = $.ajax({
        url: '/Threshold/GetModels',
        type: 'POST',
        data: '{ CategoryID: ' + catId.toString() + ', ManufacturerID: ' + manuId.toString() + ' }',
        contentType: 'application/json',
        dataType: 'json',
        cache: false,
        async: true
    });

    // received list of models...
    jqxhr.done(function (data) {
        if (data == null) return;

        try {
            var ddl = $('#ItemDescriptionID');

            // add each item to DDL
            $.each(data, function (index, value) {
                ddl.append($('<option/>', {value: data[index].ItemDescriptionID}).html(data[index].ItemDescription))
            });
        }
        catch (result) {
            alert("Done, but with errors! " + result.responseText);
        }
    });

    // failed to retrieve data
    jqxhr.error(function (result) {
        alert("Error! Failed to retrieve models! " + result.responseText);
    });
}

那我在做什么错? 如果我删除了必需的元数据标签,该表单将提交。 此外,提交表单后,我可以从下拉列表中获取ID,一切正常。 问题出在某种程度上与模型状态/验证有关。

编辑:

这是我用于说明框的剃刀...

@Html.DropDownListFor(m => m.ItemDescriptionID, new SelectList(new List<SelectListItem>()) )
@Html.ValidationMessageFor(m => m.ItemDescriptionID)

如果我正确理解了您的问题,那么您会看到的问题是,即使用户没有从下拉菜单中选择任何有效的内容,他们仍然可以发布到服务器。 当用户未选择任何ModelState.IsValid为false并收到正确的错误消息时,Model似乎正在正确验证。 但是,如果没有选择,则要完全避免发布数据。

这里的问题是ModelState和所有MVC验证实际上是在服务器端完成的。 因此,根据您模型的数据注释,为了使您的应用程序检测到用户的选择无效,确实需要提交表单。

为了阻止用户发布,您想要的是客户端验证,它不是MVC Model验证的一部分,但MVC 4内置了对它的支持。

内置MVC 4客户端验证

为了启用带有内置MVC 4 jQuery验证的客户端验证,请执行以下操作。

  • 启用MVC客户端验证支持

    确保“ Unobtrusive JavaScript”(将输出所需的HTML属性)和“ Client Side Validation”(将连接javascript)两者。

    在web.config中(对于整个站点)

     <appSettings> <add key="ClientValidationEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/> </appSettings> 

    或在代码中-global.asax.cs,视图或控制器,具体取决于所需的范围

     HtmlHelper.ClientValidationEnabled = true; HtmlHelper.UnobtrusiveJavaScriptEnabled = true; 
  • 在视图中包括所需的脚本

    MVC 4已准备好一个捆绑包,其中包括jQuery验证和简洁的验证脚本。 这必须在jQuery包之后添加。

     @Scripts.Render("~/bundles/jqueryval") 

始终检查ModelState.IsValid

即使启用了客户端验证,也必须在执行任何操作之前对发布的数据执行服务器端验证。 用户提交的数据有效还是无效,您的ActionMethod仍将执行...因此,在对已提交的数据执行操作之前,需要检查IsValid。

      [HttpPost]
      public ActionResult ActionMethodName(ModelClass modelParameterName)
      {
       //exit directly on invalid data
       if(!ModelState.IsValid) return View(modelParameterName);
       //okay to save data etc...
       ...
       ...
       //return whatever makes sense for your scenario
       return View(modelParameterName); 
      }

其他选择

您也可以手动使用jQuery验证或其他第三方javascript验证库。

自定义javascript表单验证也是一个选项-从表单的Submit事件中调用的函数返回false。

HTML5支持客户端验证属性(在您的情况下为“必需”),尽管并非所有浏览器都实现。

如果您在不使用MVC 4不引人注目的脚本的情况下自行执行验证,则应启用内置功能以避免冲突并减小返回的HTML的大小。

    <appSettings>
        <add key="ClientValidationEnabled" value="false"/>
        <add key="UnobtrusiveJavaScriptEnabled" value="false"/>
    </appSettings>

或在代码中可以控制要应用的范围。

    HtmlHelper.ClientValidationEnabled = false;
    HtmlHelper.UnobtrusiveJavaScriptEnabled = false;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM