MVC jQuery Ajax表单服务器端验证

MVC jQuery Ajax表单服务器端验证

问题描述:

我们的网站上有许多用jquery .dialog显示的表单,我们使用ajax发布请求提交它们.

We have a number of forms on our site that are shown with jquery .dialog and we submit them using an ajax post request.

我已经做了相当多的研究,并且我可以确定,由于ajax请求,如何从服务器端返回验证错误没有明确的模式.

I've done a fair bit of research and from what I can tell there isn't any definite patterns on how to return validation errors from the server side as a result of an ajax request.

我几乎唯一可以找到的模式是发布表单,然后进行验证服务器端,无论哪种情况,都返回一个封装了结果的json对象,如果结果不正确,则返回html表单

Pretty much the only pattern I could find was to post the form and then do validation server side and in either case return a json object that encapsulated a result and if the result was incorrect the form html

即.

{result: true}
{success: false, html =  "<form>....</form>"}

因此,在结果为假的情况下,您将需要重新整理与表单项相关的所有事件,因为您将用具有验证错误的新表单替换旧表单.

So in the case the result was false you would need to rewire up any events attached to items on the form as you would be replacing the old form with the new form that has the validation errors.

这似乎是一种不错的方法,但是当它们仅真正需要验证消息时,您还可能最终向客户端返回更多数据,并且还*重新连接表单,这有点烦人

This seems like an ok approach but you also end up potentially returning a lot more data to the client that you need to when they only really need to validation messages and you are also forced to rewire the form up which is a bit annoying.

我确实找到了另一种提法,即以某种方式获取验证错误并从操作中将其返回到json对象中,并以某种方式告诉客户端针对正确的字段进行显示.

I did find one other mention of somehow getting the validation errors and returning them in a json object from the action and somehow telling the client to display them against the correct fields.

有没有使它更容易使用的框架,或者我应该编写自己的框架还是只坚持返回表单的整个部分并在验证不正确时重新布线?

Is there any frameworks out there that make this easier or should I write my own or just stick to returning the entire partial for the form and rewiring it when validation is incorrect?

我不知道有什么框架可以处理这种特殊情况-我也不知道有一个明确的最佳实践-但序列化很容易验证错误,并将其作为JSON对象返回.您可以在ModelStateDictionary上尝试这种扩展方法:

I don't know of any frameworks that handle this particular case–and I don't know that there's a clear best practice–but it's easy enough to serialize validation errors and return them as a JSON object. You could try this extension method on ModelStateDictionary:

public static IEnumerable<ValidationResult> GetValidationResults(this ModelStateDictionary dictionary)
{
    foreach (var key in dictionary.Keys)
        foreach (var error in dictionary[key].Errors)
            if (error != null)
                yield return new ValidationResult(error.ErrorMessage, new string[] { key });
}

在控制器中:

if (!ModelState.IsValid)
{
    return new JsonResult(ModelState.GetValidationResults());
}

但是您是对的,然后您将不得不遍历对象并将错误附加到正确的字段.如果将ClientValidationEnabled和UnobtrusiveJavaScriptEnabled设置为true,则循环将如下所示:

But you're right, you would then have to loop through the object and append the errors to the correct fields. If you have ClientValidationEnabled and UnobtrusiveJavaScriptEnabled set to true, the loop would look something like this:

$.each(errors, function(i, item) {
    $('span[data-valmsg-for=' + item.MemberNames[0] + ']').html(item.ErrorMessage);
})

如果没有,将错误消息与它们各自的字段进行匹配将不会很困难,因为对象包含字段名称.这肯定会为您节省一些数据,但是它将验证责任的大部分转移到了Javascript中.就像我说的那样,我不知道有一个明确的最佳实践,但是我过去曾经成功地使用过这种方法.

If not, it wouldn't be that difficult to match up the error messages to their respective fields as the object contains the field name. This would definitely save you some data across the wire, but it moves a larger share of the validation responsibility into Javascript. Like I said, I don't know that there's a clear best practice, but I have used this method in the past with success.