我正在使用asp.net mvc 3开发一个Web应用程序,我有一些表单可以POST到异步操作(通过ajax)。此操作将返回带有一些数据注释的ViewModel以对其进行验证。验证工作正常,但当验证器返回错误时,我不知道如何将其返回到我的视图中显示(因为POST是由ajax制作的)。
我的行动是这样的:
[HttpPost]
public ActionResult SaveCustomer(CustomerViewModel input) {
if (!ModelState.IsValid) { // <-- business validation
return Json(new { success = false, errors = ???});
}
// persist
return Json(new { success = true });
}
如何在视图中使用jquery validate显示此错误? 如果有可能发布一些代码进行抽样......我会认为这样做!
谢谢你们!
答案 0 :(得分:49)
如果出现错误而不是发送JSON,我会将表单放在partial中,然后让控制器操作在发生错误时返回此部分。 JSON的问题在于你实际上可以使用LINQ从ModelState中获取错误,但它可能是一个PITA来在视图上显示它们。
所以:
<div id="myform">
@Html.Partial("_MyForm")
</div>
然后在_MyForm.cshtml
内:
@model CustomerViewModel
@using (Html.BeginForm())
{
@Html.EditorFor(x => x.Foo)
@Html.ValidationMessageFor(x => x.Foo)
<br />
@Html.EditorFor(x => x.Bar)
@Html.ValidationMessageFor(x => x.Bar)
<br />
<input type="submit" value="OK" />
}
并且控制器操作将变为:
[HttpPost]
public ActionResult SaveCustomer(CustomerViewModel model)
{
if (!ModelState.IsValid)
{
return PartialView("_MyForm", model);
}
return Json(new { success = true });
}
最后一步是AJAXify这个表单,可以在一个单独的javascript文件中完成:
$(function () {
$('#myform').delegate('form', 'submit', function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
// We have a JSON object in case of success
alert('success');
} else {
// We have the partial with errors in case of failure
// so all we have to do is update the DOM
$('#myform').html(result);
}
}
});
return false;
});
});
答案 1 :(得分:15)
您可以返回ModelState错误。这是未经测试的,但这样的事情应该有效。
return Json(new
{
success = false,
errors = ModelState.Keys.SelectMany(k => ModelState[k].Errors)
.Select(m => m.ErrorMessage).ToArray()
});
编辑:要在视图中显示错误,您只需检查是否成功,如果没有,则迭代错误列表并将其放在显示错误的位置。
if(!result.success) {
for(var error in result.errors) {
$('#errorMessages').append(error + '<br />');
}
}
我更喜欢Darin对大多数项目的回答,但您的消费者可能并不总是您自己的应用程序,在这种情况下返回错误列表更合适,因为它会允许消费者显示他们想要的错误。
答案 2 :(得分:0)
创建一个类来表示各个属性的ModelState错误。
public class ValidationError
{
public string PropertyName = "";
public string[] ErrorList = null;
}
创建一个基于ModelState返回ValidationErrors列表的方法
public IEnumerable<ValidationError> GetModelStateErrors(ModelStateDictionary modelState)
{
var errors = (from m in modelState
where m.Value.Errors.Count() > 0
select
new ValidationError
{
PropertyName = m.Key,
ErrorList = (from msg in m.Value.Errors
select msg.ErrorMessage).ToArray()
})
.AsEnumerable();
return errors;
}
然后在控制器的Post方法中执行以下操作:
if (!ModelState.IsValid)
{
return Json(new
{
errors = true,
errorList = GetModelStateErrors(ModelState)
}, JsonRequestBehavior.AllowGet);
}
您可以创建一个遍历上面返回的错误列表的JS函数
$.ajax({
cache: false,
async: true,
type: "POST",
url: form.attr('action'),
data: form.serialize(),
success: function (data) {
if (data.errors) {
displayValidationErrors(data.errorList);
}
},
error: function (result) {
console.log("Error");
}
});
function displayValidationErrors(errors) {
$.each(errors, function (idx, validationError) {
$("span[data-valmsg-for='" + validationError.PropertyName + "']").text(validationError. ErrorList[0]);
});
}
在上面的示例中,我仅从“ ErrorList”中收到第一条错误消息。您可以创建一个附加循环以获取所有消息并追加到您的验证范围内。
答案 3 :(得分:0)
尝试此代码。这是解决您问题的简单方法。它将所有模型状态错误合并为一个字符串。
[HttpPost]
public ActionResult SaveCustomer(CustomerViewModel input) {
if (!ModelState.IsValid) { // <-- business validation
return Json(new { success = false, errors = string.Join("; ", ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => x.ErrorMessage));});
}
// persist
return Json(new { success = true });
}