2017-04-19 55 views
0

我有一个类列表的Json解析错误,检测部分对象JSON格式错误 - ASPNET的WebAPI

class Sample 
{ 
    public string str1; 
    public string str2; 
    public string str3; 
    public string str4; 
    public DateTime date1; 
    public DateTime date2; 
} 

而且我使用Aspnet Webapi Http Post方法和需要解析的身体,

一般来说,如果人体的JSON格式有很大的误差,如在一开始缺乏支架:

[ 
"str1": "32226","str2":"ABC","str3" :"91492","str4":"AC","date1":"1997-04-23T18:25:43", 
"date2":"1997-04-23T18:25:43" 
}, 
{"str1": "3226","str2":"ABF","str3" :"492","str4":"AB","date1":"1997-04-23T18:25:43","date2":"1997-04-23T18:25:43" 
} 
] 

使用时[FromBody]List<Sample> samples解析身体,你会得到samples = null,所以你可以使用空讲,人体的JSON格式错误,

但是当我尝试只是做一个物业的日期时间JSON格式错误,如DATE2在下面的第一个对象:

[ 
{"str1": "32226","str2":"ABC","str3" :"91492","str4":"AC","date1":"1997-04-23T18:25:43", 
"date2":"1997-04-2325:43" -> date2 error datetime string 
}, 
{"str1": "3226","str2":"ABF","str3" :"492","str4":"AB","date1":"1997-04-23T18:25:43","date2":"1997-04-23T18:25:43" 
} 
] 

然后使用[FromBody]List<Sample> samples解析,它可以成功地解析第二个对象,并显示列表计数为samples等于1,

但是没有任何异常或信息我可以告诉第一个对象是JSON解析失败,如果两个对象是所有解析正确将使samples Count is 2.

我尝试将DateTime Type更改为DateTime ?,但是,只有第二个对象被解析,并且第一个对象被默认省略。

有什么办法来检测这种错误,只有一些对象的JSON格式是错误的?

我能想到一个简单的方法是计数炭{当今时代,并比较了表计数值,如果{的计数<清单算的话,必须有一些对象不能成功地解析,但似乎不是一个好方法。

回答

1

but there isn't any exception or information I can tell that the first object's is JSON Parsed Failed

是的,有一种方法可以看到,如果JSON与错误解析

Application_Start() 只是做以下

protected void Application_Start() 
    { 
     GlobalConfiguration.Configure(WebApiConfig.Register); 
     GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Error += 
      delegate(object sender, ErrorEventArgs args) 
      { 

       File.WriteAllText(@"c:\\temp\\jsonerrortest.txt", args.ErrorContext.Error.Message);          

      }; 
    } 

更新

从您的评论:

Is there way to tell during the execution? I want to tell the parsed error in the post method and throw an exception inform the user that the input body is wrong.

是有办法FO这样做,你有DelegatingHandler 类似以下拦截您messgae:

public class MessageHandler : DelegatingHandler 
{ 

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 

     string requestInfo = string.Empty; 



      requestInfo = string.Format("{0}:{1}", request.Method, request.RequestUri); 
      var requestMessage = await request.Content.ReadAsByteArrayAsync(); 
      IncommingMessageAsync(requestInfo, requestMessage); 


     var response = await base.SendAsync(request, cancellationToken); 

      byte[] responseMessage; 

      if (response.IsSuccessStatusCode) 
      { 
       if (response.Content != null) 
        responseMessage = await response.Content.ReadAsByteArrayAsync(); 
       else 
        responseMessage = Encoding.UTF8.GetBytes(response.ReasonPhrase); 

      } 
      else 
       responseMessage = Encoding.UTF8.GetBytes(response.ReasonPhrase);   
      OutgoingMessageAsync(requestInfo, responseMessage);   

     return response; 
    } 
    protected void IncommingMessageAsync(string requestInfo, byte[] message) 
    { 

     var obj =JObject.Parse(Convert.ToString(message)); 
    }  
    protected void OutgoingMessageAsync(string requestInfo, byte[] message) 
    { 

    } 
} 

注意:在您IncomingMessageAsync如果有是

var obj =JObject.Parse(Convert.ToString(message)); 

这将提高在详细模式下例外解析错误的情况下

{ 
    "Message": "An error has occurred.", 
    "ExceptionMessage": "Unexpected character encountered while parsing value: S. Path '', line 0, position 0.", 
    "ExceptionType": "Newtonsoft.Json.JsonReaderException", 
    "StackTrace": " à Newtonsoft.Json.JsonTextReader.ParseValue()\r\n à Newtonsoft.Json.JsonTextReader.Read()\r\n à Newtonsoft.Json.Linq.JObject.Load(JsonReader reader)\r\n à Newtonsoft.Json.Linq.JObject.Parse(String json)\r\n à MessageHandler.IncommingMessageAsync(String requestInfo, Byte[] message) dans c:\\tests\\WebApplication2\\WebApplication2\\MessageHandler.cs:ligne 45\r\n à MessageHandler.<SendAsync>d__0.MoveNext() dans c:\\tests\\WebApplication2\\WebApplication2\\MessageHandler.cs:ligne 21\r\n--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---\r\n à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n à System.Web.Http.HttpServer.<SendAsync>d__0.MoveNext()" 
} 

注意 出于安全原因永远不要做这个

创建一个自定义异常,而不是

+0

谢谢您回答,我会稍后再尝试。有没有办法在执行逻辑代码中告诉?我想在post方法中告诉解析错误,这样我可以返回一个异常HttpResponseMessage来通知用户何时输入正文错误。 –