反序列化带有转义字符的字符串时出错

时间:2017-02-28 20:47:07

标签: c# json json.net asp.net-web-api2 deserialization

我希望这是非常简单的事情,并且必须是其他开发者的常见场景。

我从SQL发送包含错误详细信息的OUT变量。在我的DataLayer API中,我在VS Debugger中检查它以及它的显示方式:

var string_from_stored_proc = "[{\"errornumber\":2627,\"errormessage\":\"Violation of UNIQUE KEY constraint 'KEY_Subject'. Cannot insert duplicate key in object 'edu.Subject'. The duplicate key value is (MATS10, 2).\",\"errorstate\":1,\"errorseverity\":14,\"errorline\":36,\"errroprocedure\":\"SPCreateSubject\",\"xactstate\":1}]"

我知道VS调试器会将escape()添加到字符串中。当我尝试使用以下命令反序列化此字符串时:

JsonConvert.DeserializeObject<my_error_object>(string_from_stored_proc);

我收到此错误:

  

{&#34;无法将当前JSON数组(例如[1,2,3])反序列化为类型   &#39; BaaS.DTO.SQLErrorHandler&#39;因为类型需要JSON对象   (例如{\&#34; name \&#34;:\&#34; value \&#34;})要正确反序列化。\ r \ n要修复此问题   错误要么将JSON更改为JSON对象(例如,   {\&#34; name \&#34;:\&#34; value \&#34;})或将反序列化类型更改为数组或   实现集合接口的类型(例如ICollection,IList)   像可以从JSON数组反序列化的List。   JsonArrayAttribute也可以添加到类型中以强制它   从JSON数组反序列化。\ r \ n路由&#39;&#39;,第1行,第1位。&#34;}

json2csharp.com无法转换此JSON。如果我删除所有反斜杠,它就可以完成任务。下面是 my_error_object (或由json2sharp转换)类:

public class my_error_object
{
    public int errornumber { get; set; }
    public string errormessage { get; set; }
    public int errorstate { get; set; }
    public int errorseverity { get; set; }
    public int errorline { get; set; }
    public string errroprocedure { get; set; }
    public int xactstate { get; set; }
}

我尝试处理 string_from_stored_proc 并删除所有反斜杠,但我无法删除转义字符(我认为这是预期的行为)。有了这些斜线,我无法将字符串反序列化。

解决方法: 如果我使用var outputJson = Newtonsoft.Json.Linq.JToken.Parse(string_from_stored_proc);,它会输出以下输出:

{[
  {
    "errornumber": 2627,
    "errormessage": "Violation of UNIQUE KEY constraint 'KEY_Subject'. Cannot insert duplicate key in object 'edu.Subject'. The duplicate key value is (MATS10, 2).",
    "errorstate": 1,
    "errorseverity": 14,
    "errorline": 36,
    "errroprocedure": "SPCreateSubject",
    "xactstate": 1
  }
]}

删除起始和尾随大括号后,可以使用NewtonSoft反序列化。

但是,当我使用BadRequest(deserialized_string_from_stored_proc)从DataLayer发送它时 并使用

在BusinessLayer中检索它
var output = await response.Content.ReadAsAsync<SQLErrorHandler>();

输出变量再次有很多额外的字符,然后我需要再次处理。对我有用的唯一方法是使用HttpResults.OK(对象)发送反序列化的对象,并在我的BusinessLayer中读取它。这是我不想做的,因为如果出现错误,它不是正确的返回类型。

我做得对吗?我有两个问题:

  1. 有没有办法反序列化给定的字符串并发送使用 没有字符串处理的BusinessLayer呢?
  2. 如果第一个不可能,我可以简单地将字符串传递给 BusinessLayer并在那里反序列化(首选方式)?
  3. 我很乐意提供更多信息或代码段来重现错误。

    修改 根据@ Equalsk的建议,我已经能够正确地反序列化它。但是,它目前在Datalayer中。这是输出:

    var equalskObj = JsonConvert.DeserializeObject<List<SQLErrorHandler>>(outputFromSP.Value.ToString());
    return Ok(equalskObj);
    

    然而,我仍然无法做出首选方式(#2)。如果我使用return BadRequest(string_from_stored_proc)将字符串发送到BusinessLayer,则会发送

      

    &#34; {\ r \ n \&#34;消息\&#34;:   \&#34; [{\\&#34; errornumber \\&#34;:2627,\\&#34; errormessage \\&#34;:\\&#34;违反   UNIQUE KEY约束&#39; KEY_Subject&#39;。无法插入重复键   对象&#39; edu.Subject&#39;。重复的键值是(MATS10,   2)\\&#34;,\\&#34; errorstate \\&#34;:1,\\&#34; errorseverity \\&#34;:14,\\&#34; errorline \ \&#34;:36,\\&#34; errroprocedure \\&#34;:\\&#34; SPCreateSubject \\&#34;,\\&#34; xactstate \\&#34 ;: 1}] \&#34; \ r \ N}&#34;

    我还需要处理它。是否有更清洁的方式将其发送然后按照建议进行转换?我想我应该为此发布一个简化的问题,因为这些都是单独的问题。我真的很想知道做什么是最好的方法。

1 个答案:

答案 0 :(得分:1)

我遇到了类似的事情。要从DL获得输出,您可以返回如下:

FROM DL(被叫/第二)API

return Content(<HttpStatusCode>, "Custom Error Message Here");

例如:

Return Content(System.Net.HttpStatusCode.BadRequest, e.Message.ToString());

现在在BL(First / Calling)API中,如果StatusCode不是Success,则读取响应结果。像这样:

if(!response.IsSuccessStatusCode)
{
    var errorOutput = response.Content.ReadAsStringAsync().Result;
    //Now send this errorOutput from this API to the client. Return an HTTPResult or another Content from here. Upto you!
}
return Ok(); //If response.statuscode is Success