微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 从ModelState中删除JSON.net序列化异常

问题背景

为了避免重复验证逻辑,我遵循将Server Side ModelState错误推送到我的View Model(MVVM KnockoutJS)的模式.

所以按照惯例我的属性名称在我的KO viewmodel匹配属性我的Api是暴露和期望,因此我可以使用一个小的Knockout插件我写的一个很容易地映射到另一个.

<validation-summary params="vm: $data,class: 'alert alert-error'"></validation-summary>

...

<div class="control-group" data-bind="errorCss: {'error': spend }">
     <label class="control-label" for="spend">Spend</label>
     <div class="controls">
        <div class="input-prepend">
           <span class="add-on">$</span>
           <input type="text" data-bind="value: spend" id="spend" class="input-medium" placeholder="Spend USD" />
         </div>   
          <validation-message params="bind: spend,class: 'text-error'"></validation-message>
      </div>
</div>

问题

我的问题是,当JSON.Net串行化我发送的JSON和AJAX,当遇到异常时,它将它添加到ModelError类的ModelState和异常.

响应示例

{
  "message": "The request is invalid.","modelState": {
    "cmd.spend": [
      "Error converting value \"ii\" to type 'System.Double'. Path 'spend',line 1,position 13.","'Spend' must be greater than '0'."
    ],"cmd.Title": [
      "'Title' should not be empty."
    ]
 }
}

问题由于这个消息并不能给出一个很好的UX:

Error converting value "ii" to type 'System.Double'. Path 'spend',position 13.

事实上,我无法将这个异常消息与我的验证消息分开,因为它们都在一个数组中.

我宁愿删除它,并在我的ValidationClass处理这个问题

我可以像这样手动删除它们,这是一个ActionFilter,所以我只有一次.

public class ValidateCommandAttribute : ActionFilterattribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            ModelStateDictionary modelState = actionContext.ModelState;

            #if !DEBUG
                for (int i = 0; i < modelState.Values.Count; i++)
                {
                    ModelErrorCollection errors = modelState.ElementAt(i).Value.Errors;
                    for (int i2 = 0; i2 < errors.Count; i2++)
                    {
                        ModelError error = errors.ElementAt(i2);
                        if (error.Exception != null)
                        {
                            // Todo: Add Log4Net Here
                            errors.RemoveAt(i2);
                        }
                    }
                }
            #endif

            if (!modelState.IsValid)
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest,modelState); 
        }
    }

我知道JSON.Net是高度可配置的,想知道API中有没有哪里可以关闭它,还是抑制它?

解决方法

你可以设置一个 error handler.例如(从json.net docs),
List<string> errors = new List<string>();

List<DateTime> c = JsonConvert.DeserializeObject<List<DateTime>>(@"[
      '2009-09-09T00:00:00Z','I am not a date and will error!',[
        1
      ],'1977-02-20T00:00:00Z',null,'2000-12-01T00:00:00Z'
    ]",new JsonSerializerSettings
    {
        Error = delegate(object sender,ErrorEventArgs args)
        {
            errors.Add(args.ErrorContext.Error.Message);
            args.ErrorContext.Handled = true;
        },Converters = { new IsoDateTimeConverter() }
    });

// 2009-09-09T00:00:00Z
// 1977-02-20T00:00:00Z
// 2000-12-01T00:00:00Z

// The string was not recognized as a valid DateTime. There is a unkNown word starting at index 0.
// Unexpected token parsing date. Expected String,got StartArray.
// Cannot convert null value to System.DateTime.

原文地址:https://www.jb51.cc/csharp/94891.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐