【问题标题】:ASP.Net MVC 3 JSON Model Binding and server side model validation mixed with client side validationASP.Net MVC 3 JSON 模型绑定和服务器端模型验证与客户端验证混合
【发布时间】:2011-01-14 12:21:20
【问题描述】:

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

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

但是如果模型无效怎么办?

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

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

这可能吗?

或者有没有我可以利用的框架来做到这一点?

【问题讨论】:

  • 你如何发布这个 JSON?你在使用 AJAX 吗?
  • @TheCodeKing 你在链接回这个问题吗?

标签: asp.net-mvc-3


【解决方案1】:

在 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 来显示错误。我已经从这个例子中排除了这一点。

【讨论】:

  • 为响应欢呼。我现在无法完全测试这个,因为我正在度假。我希望你不介意我把它打开直到我回来?
  • @Junto 为什么不使用布尔值而不是枚举?
  • @Rushino 您可以扩展枚举以包含例如警告或信息。布尔值限制你。
【解决方案2】:

感谢您提供此解决方案。我通过传递字典对其进行了一些改进,以便您可以使用不显眼的 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;
    }

【讨论】:

  • 我真的想知道你是如何在客户端将错误从 json 绑定到你的表单 - 你能解释一下吗?
【解决方案3】:

@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);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2017-01-26
    • 2011-11-04
    • 1970-01-01
    • 2017-05-03
    • 2013-11-24
    相关资源
    最近更新 更多