JavaScript 填充的下拉列表在 ModelState 中无效
JavaScript populated DropDown not valid in ModelState
我在做什么:我有 3 个组合框。前 2 个框中的选择决定了第三个框中的列表。每当在前 2 个框中的任何一个中进行选择时,我都会运行一些 jQuery,该查询进行 $.ajax 调用以获取第三个框的列表。第三个框是我的"项目描述"框。
问题:jquery ajax 调用有效。当我选择前 2 个框中的值时,项目描述将加载到第三个框中。但是,当我尝试提交表单时,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 并且您收到正确的错误消息时,模型似乎正在正确验证。但是,如果尚未进行选择,则希望完全避免发布数据。
这里的问题是ModelState和所有MVC验证实际上是在服务器端完成的。因此,为了让您的应用程序根据模型的数据注释检测到用户的选择无效,确实需要提交表单。
为了阻止用户发布,你想要的是客户端验证,这不是MVC模型验证的一部分,但MVC 4内置了对它的支持。
内置 MVC 4 客户端验证
为了使用内置的MVC 4 jQuery验证启用客户端验证,请执行以下操作。
-
启用 MVC 客户端验证支持
确保"不显眼的JavaScript"(将输出所需的HTML属性)和"客户端验证"(将连接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")
始终检查模型状态是否有效
即使启用了客户端验证,也必须在执行任何操作之前对发布的数据执行服务器端验证。无论用户提交的数据是有效还是无效,您的操作方法仍将执行...因此,在对已提交的数据执行操作之前,您需要检查 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 表单验证也是一个选项 - 从表单的提交事件调用的函数返回 false。
HTML5 支持客户端验证属性(在您的情况下为"必需"),尽管并非所有浏览器都实现它。
如果您在不使用 MVC 4 不显眼的脚本的情况下自己执行验证,则应关闭内置功能以避免冲突并减小返回的 HTML 的大小。
<appSettings>
<add key="ClientValidationEnabled" value="false"/>
<add key="UnobtrusiveJavaScriptEnabled" value="false"/>
</appSettings>
或者在代码中,您可以控制要应用的范围。
HtmlHelper.ClientValidationEnabled = false;
HtmlHelper.UnobtrusiveJavaScriptEnabled = false;
- 如果我在javascript中输入无效的电子邮件或空白,如何显示特定的文本框边框红色
- jquery代码在Mozilla中有效,但在其他浏览器上无效
- 这个问号在Flow中意味着什么:“;?()=>“无效”;
- 从字符串末尾删除空白无效
- Jquery Datatables错误:无效的JSON基元:draw
- 滚动在Chrome中有效,但在Firefox或IE中无效
- 错误:语法错误,无法识别的表达式:不支持的伪:无效/RectJS/Unit Testing
- Javascript setattribute-名称和值无效
- 格式化货币无效
- JavaScript错误无效的限定符
- 按键事件无效的原因
- Laravel数据表无效的JSON响应
- 文本字段显示它是有效的,即使它在ExtJS中是无效的
- JS代码在jsbin中有效,在jsfiddle或Chrome/Safari中无效
- 如何使用JavaScript粘贴原始二进制文件而不出现“无效字符”错误
- Xpath对Selenium Web驱动程序无效”;Xpath未找到”;
- 电子邮件地址验证但创建帐户,即使电子邮件地址无效
- 为什么这个按钮在IE中有效,但在Firefox中无效
- JavaScript 填充的下拉列表在 ModelState 中无效
- 通过jquery ajax在Web Api中显示无效的ModelState