ASP.Net MVC 3 JSON模型绑定和服务器端模型验证与客户端验证混合

时间:2011-01-14 12:21:20

标签: asp.net-mvc-3

我一直在玩新的MVC3 Json模型绑定,它非常好。

目前,我可以将JSON发布到控制器并绑定它。模型验证也很好。

但是如果模型无效会怎样?

我想返回JSON并让客户端通知用户(就像你在mvc中执行正常的客户端验证一样)

有没有人知道如何执行此操作的一些教程?

这甚至可能吗?

或者我可以利用这些框架来实现这一目标吗?

3 个答案:

答案 0 :(得分:25)

以下示例适用于在MVC3中使用不显眼的JavaScript时。我正在做一些非常相似的事情。鉴于以下JsonResponse类:

public enum Status
{
    Ok,
    Error
}

public class JsonResponse
{
    public Status Status { get; set; }
    public string Message { get; set; }
    public List<string> Errors { get; set; }
}

我的控制器可以有一个方法:

[HttpPost]
public ActionResult Login(UserLoginModel model)
{
    JsonResponse res = new JsonResponse();

    if (!ModelState.IsValid)
    {
        res.Status = Status.Error;
        res.Errors = GetModelStateErrorsAsString(this.ModelState);
        res.Message = "Oh dear, what have you done. Check the list of errors dude!";
    }
    else
    {
        // Save it here...

        // Return success
        res.Status = Status.Ok;
        res.Message = "Everything was hunky dory";
    }            

    return Json(res);
}

可以为错误枚举ModelStateDictionary,如下所示:

private List<string> GetModelStateErrorsAsString(ModelStateDictionary state)
{
    List<string> errors = new List<string>();

    foreach (var key in ModelState.Keys)
    {
        var error = ModelState[key].Errors.FirstOrDefault();
        if (error != null)
        {
            errors.Add(error.ErrorMessage);
        }
    }

    return errors;
}

然后在我看来,我可以进行以下JSON POST:

<script type="text/javascript">
$("form").submit(function (evt) {
    // validate
    $('form').valid();

    // extract values to submit         
    var form = $(this),
        username = form.find("[name=Username]").val(),
        password = form.find("[name=Password]").val(),
        json = JSON.stringify({
            Username: username,
            Password: password
        });

    $.ajax({
        url: form.attr("action"),
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        data: json,
        success: function (result) {
            alert(result.Message);
        }
    });

    // stop form submitting
    evt.preventDefault();
});
</script>

我正在使用jQuery.tmpl来显示错误。我已经从这个例子中排除了这个。

答案 1 :(得分:1)

感谢您提供此解决方案。我通过传递字典来改进它,以便您可以使用不显眼的javascript通过引用字典的键将验证放在单个字段而不是摘要上。

    private Dictionary<string, string> GetModelStateErrorsAsString(ModelStateDictionary state)
    {
        Dictionary<string, string> errors = new Dictionary<string, string>();
        foreach (var key in ModelState.Keys)
        {
            var error = ModelState[key].Errors.FirstOrDefault();
            if (error != null)
            {
                errors.Add(key, error.ErrorMessage);
            }
        }
        return errors;
    }

答案 2 :(得分:0)

@Junto和@Jamey777,你们都将ModelState传递给你的错误函数,然后你使用全局变量而不是参数。

为什么你不只是使用像Linq那样的

    private Dictionary<string, string> GetModelStateErrorsAsString()
    {
        return ModelState.Where(x=> x.Value.Errors.Any())
            .ToDictionary(x => x.Key, x => x.Value.Errors.First().ErrorMessage);
    }