JSON.NET Parser *似乎*对我的对象进行双重序列化

Posted

技术标签:

【中文标题】JSON.NET Parser *似乎*对我的对象进行双重序列化【英文标题】:JSON.NET Parser *seems* to be double serializing my objects 【发布时间】:2014-10-22 22:17:01 【问题描述】:

我的问题是这样的:

这是从我的 WebAPI 控制器发回的响应。

"[
   [
      \"id\":\"identifier\",
      \"name\":\"foobar\"
   ]
]"

请注意,响应包含在引号中,并且所有嵌入的引号都被转义了。这显然是个问题。我可以向 JSON.NET 序列化程序提供任何设置来防止这种情况发生吗?

编辑

正如 p.s.w.g 在他的回复中猜测的那样,我使用的是 JSON.NET 的

JsonConvert.SerializeObject(instance)

执行我的序列化。

我这样做是因为在构建自定义转换器时,我已将它们包含在我的 WepApiConfig 中的 JsonConvert.DefaultSettings 中(我显然认为这不会成为问题)

我之前曾尝试将我的 HttpGets 的返回类型交换为“我的对象类型”,并且响应是我的对象的 ToString() 方法的 json 表示...这让我知道序列化没有通过我的转换器.

将我的 HttpGets 的返回类型从字符串更改为“我的对象类型”并将这些转换器直接插入 WebAPi 的默认 HttpConfiguration 就可以了。

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new FooConverter());
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new BarConverter());

简单易懂。

【问题讨论】:

你能显示 API 操作吗? 【参考方案1】:

你可能有这样的事情:

public string GetFoobars()

    var foobars = ...
    return JsonConvert.SerializeObject(foobars);

在这种情况下,您使用 Json.NET 将对象序列化为字符串,然后通过将结果作为字符串返回,API 控制器会将字符串序列化为 javascript 字符串字面量——这将导致字符串被包装在双引号中,并导致字符串中的任何其他特殊字符用反斜杠转义。

解决方案是简单地自己返回对象:

public IEnumerable<Foobar> GetFoobars()

    var foobars = ...
    return foobars;

这将导致 API 控制器使用其默认设置序列化对象,这意味着它将根据从客户端传入的参数将结果序列化为 XML 或 JSON。

进一步阅读

JSON and XML Serialization in ASP.NET Web API

【讨论】:

你的***sn-p正是我正在做的。我在我的对象上调用 JsonConvert.SerializeObject。 (我不在我的开发机器上,或者我只是直接测试)在 WebAPI 将其放入响应之前返回对象是否会通过 JSON.NET 转换器? @K.AlanBates 是的,如果你参考链接的文档,你会看到这将使用JsonMediaTypeFormatter,而它又默认使用 Json.NET。 在这一点上,我认为我必须提到我必须使用我自己的 JsonConverters 来完成这项任务可能很重要。我从最初的描述中删除了它们,因为我不想提供不相关的信息。我需要能够调用 JsonConvert.SerializeObject(或将使用我的转换器的等效方法)并让它返回 json 而不是字符串。返回一个对象只不过是序列化对象的 ToString() 而我不能拥有它。我也没有可使用的 DataContract。 @K.AlanBates 如果您使用[JsonConverter] 属性注释类,这应该不是问题。如果您不控制这些类并且无法添加任何属性,可以直接在您的 WebApiConfig.cs 文件(或类似文件)中调整全局 JsonMediaTypeFormatter 过去几分钟我一直在尝试远程进入我的开发箱以查看我的 WebApiConfig 设置,因为我可以发誓我已经配置了我的 JsonMediaTypeFormatter。我还将自定义转换器添加到 SerializerSettings 并调用 JsonConvert.SerializeObject(instance) 调用我的转换器但返回字符串转义的 JSON。我在连接时遇到问题,所以我必须把它搁置到明天早上我可以确认我当前的配置时。感谢您迄今为止的帮助。【参考方案2】:

API 在发送响应之前进行序列化。 示例:返回 Ok(yourUnSerializedObject);

无需为您排忧解难。

【讨论】:

【参考方案3】:

检查您的属性修饰符。举例:

  public List<Yourobjectclass> columnaLista  get; set; 

    public List<Yourobjectclass> ColumnaLista
    
        get
        
            return this.columnaLista;
        
        set
        
            this.columnaLista = value;
        

序列化程序将添加 columnaLista 的所有对象而不管名称,因为您有两个带有 public 修饰符的属性。

要解决这个问题,您必须像这样更改属性修饰符:

      private List<Yourobjectclass> columnaLista  get; set; 

【讨论】:

这个问题在 6 年前就已经解决了。核心问题是自定义转换器没有被合并到 HttpConfiguration 中 JsonFormatter 的 SerializerSettings 中。 config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new CustomConverter()); 纠正了这个问题。 (这在我接受答案后的问题的编辑部分中都有详细说明)

以上是关于JSON.NET Parser *似乎*对我的对象进行双重序列化的主要内容,如果未能解决你的问题,请参考以下文章

在序列化之前根据模式验证对象

在反序列化时如何忽略JSON对象数组中的空白数组?

为啥 STL 优先级队列错误地对我的类对象进行排序

使用 C# 解析复杂的 JSON

将实体框架对象序列化为 JSON

Json.NET 问题