【问题标题】:error while de-serializing string with escape characters in it反序列化带有转义字符的字符串时出错
【发布时间】:2017-02-28 20:47:07
【问题描述】:

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

我正在从 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 调试器将转义 () 添加到字符串中。 当我尝试使用以下方法反序列化此字符串时:

JsonConvert.DeserializeObject<my_error_object>(string_from_stored_proc);

我收到此错误:

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

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(object) 发送反序列化对象并在我的 BusinessLayer 中读取它。我不想这样做,因为在发生错误时它不是正确的返回类型。

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

  1. 有没有办法反序列化给定的字符串并使用 给BusinessLayer不用字符串处理吗?
  2. 如果 first 不可能,我可以简单地将字符串传递给 BusinessLayer 并在那里反序列化(首选方式)?

我很高兴提供更多信息或代码 sn-p 来重现错误。

编辑: 根据@Equalsk 的建议,我已经能够正确反序列化它。但是,它目前在数据层中。这是输出:

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

但是,我仍然无法采用首选方式(#2)。如果我使用 return BadRequest(string_from_stored_proc) 将字符串发送到 BusinessLayer,它会发送

"{\r\n \"消息\": \"[{\\"errornumber\\":2627,\\"errormessage\\":\\"违规 唯一键约束“KEY_Subject”。无法插入重复键 对象'edu.Subject'。重复键值为 (MATS10, 2).\\",\\"errorstate\\":1,\\"errorseverity\\":14,\\"errorline\\":36,\\"errroprocedure\\":\\"SPCreateSubject\ \",\\"xactstate\\":1}]\"\r\n}"

我仍然需要处理它。有没有更干净的方式发送它然后按照建议进行转换?我想我应该为此发布一个简化的问题,因为这些是单独的问题。我真的很想看看最好的方法是什么。

【问题讨论】:

  • 你试过JsonConvert.DeserializeObject&lt;List&lt;my_error_object&gt;&gt;(string_from_stored_proc);吗?
  • 它正在寻找列表/数组类型,因为您的 SQL 字符串在其内容周围有 [ 和 ]。删除那些,然后反序列化。
  • @Equalsk - 非常感谢。它成功了。我不知何故忽略了它正在返回一个列表,即使在存储过程中设置的返回变量是一个 varchar(C# 模型中的字符串)。
  • 但是,我仍然坚持使用 return Ok(object),而不是能够使用 BadRequest(string_from_stored_proc) 发送干净的错误字符串并在 BusinessLayer 中对其进行反序列化。我已经用输出更新了问题。再次感谢。 @MikeMcCaughan - 虽然你的答案有效,但我首先不想这样做,因为它涉及手动字符串处理。

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


【解决方案1】:

我被类似的事情困住了。要从您的 DL 中获取输出,您可以返回如下:

来自 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

【讨论】:

  • 这很有帮助。传递内容更好,因为它支持自定义错误/消息以及状态代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
相关资源
最近更新 更多