[英]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 jQuery验证的客户端验证,请执行以下操作。
确保“ 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")
即使启用了客户端验证,也必须在执行任何操作之前对发布的数据执行服务器端验证。 用户提交的数据有效还是无效,您的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.