【问题标题】:JSON serializer adding extra character as '\'in response while serializing custom datatype in custom JsonConverterJSON 序列化程序在自定义 JsonConverter 中序列化自定义数据类型时添加额外字符作为响应
【发布时间】:2015-11-04 14:26:57
【问题描述】:

我正在使用自定义 JsonConverter(CustomInfoConverter) 对正在解析的每个自定义点网类型(CustomType) 进行一些操作。

下面是自定义JsonConverter的代码:

public class CustomInfoConverter : JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(CustomType);
    }
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var customType = (CustomType)value;
        if (customType == null || null== customType.TimeZone) return;
        //DateTime currentDateTime = customType.Date??DateTime.Now;
        DateTime currentDateTime = DateTime.SpecifyKind(customType.Date ?? DateTime.Now, DateTimeKind.Unspecified);

        DateTime userDateTime = TimeZoneInfo.ConvertTimeFromUtc(currentDateTime, customType.TimeZone);
        customType.Date = userDateTime;
        writer.WriteValue(JsonConvert.SerializeObject(customType) );


    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }


}

我在这里面临的问题是额外的字符'\' 被附加到这里,所以我的回复看起来像JsonConvert.SerializeObject(customType) 正在序列化 customType 对象,而默认序列化程序正在序列化它(如果我错了,请纠正我)。有什么办法解决这个问题?

   {
  "Data": [
    {
      "Type": "someThing",
      "Created": "{\"Date\":\"2015-11-05T01:09:21.6721171+05:30\",\"User\":{\"Upn\":\"james\",\"FirstName\":\"James\",\"LastName\":\"Johnson\",\"Id\":\"69cb471e-da83-48c3-8f60-d1bb29d41177\",\"Name\":\"Johnson\"},\"TimeZone\":{\"Id\":\"India Standard Time\",\"DisplayName\":\"(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi\",\"StandardName\":\"India Standard Time\",\"DaylightName\":\"India Daylight Time\",\"BaseUtcOffset\":\"05:30:00\",\"AdjustmentRules\":null,\"SupportsDaylightSavingTime\":false},\"Latitude\":null,\"Longitude\":null}",
    }
  ],

}

here了解到,可能是因为re-json-ing, 那么,解决这个问题的方法是什么?

【问题讨论】:

  • 你能给 json 提供额外的 '\',你的字符串看起来很好,除了最后缺少 ",是你的错误输入还是这正是你的 json(那时它不起作用全部)?
  • 用完整的 json 响应编辑了问题

标签: c# json serialization json.net


【解决方案1】:

问题出在这一行:

writer.WriteValue(JsonConvert.SerializeObject(customType));

相反,您应该这样做以避免双重序列化:

serializer.Serialize(writer, customType);

但是,由于您尝试序列化转换器转换的同一对象,因此上述将导致自引用循环。在这种情况下,您需要使用序列化程序的新实例。试试这个:

new JsonSerializer().Serialize(writer, customType);

注意:如果您使用任何其他转换器(或自定义设置),新的序列化程序实例将不知道它们,除非您专门从外部序列化程序复制它们。如果您需要这样做,请确保CustomInfoConverter 复制到新实例,否则您将再次遇到自引用循环问题。要复制转换器,请将上面的内容替换为以下内容:

JsonSerializer innerSerializer = new JsonSerializer();
foreach (var converter in serializer.Converters.Where(c => !(c is CustomInfoConverter)))
{
    innerSerializer.Converters.Add(converter);
}
innerSerializer.Serialize(writer, customType);

【讨论】:

  • 在这种情况下,我面临以下运行时异常 在 Newtonsoft.Json.dll 中发生“Newtonsoft.Json.JsonSerializationException”类型的异常,但未在用户代码中处理附加信息:检测到自引用循环输入“自定义类型”。路径“数据 [0]”。
  • 啊,是的。问题是您正在序列化转换器转换的同一对象。所以这将导致一个递归循环——转换器调用序列化程序,然后调用转换器,然后调用序列化程序等。您可以通过使用序列化程序的新实例来解决这个问题。我已经编辑了我的答案。
  • 非常感谢@Brain,它正在工作,但它导致了一个问题。我有另一个名为 TimeZoneInfoConverter 的 JsonConverter 将时区转换为其首字母(“印度标准时间”为“IST”) ,在使用此代码而不是得到“IST”作为响应后,我得到了“印度标准时间”。这可能是 TimeZoneInfoConverter 没有被触发,因为 customType 有一个 TimeZoneInfo 类型的属性。还有其他可能的原因吗?我在 JsonContentNegotiator 中的 TimeZoneInfoConverter 之后注册了 CustomInfoConverter 也尝试了反之亦然,但没有运气:(
  • 啊。您没有提到您正在使用其他转换器。问题是我们在这里创建的新 JsonSerializer 实例不了解其他转换器。因此,您需要将它们从外部序列化程序复制到新实例。但是,您需要确保不要将CustomInfoConverter 复制到新的序列化程序,否则您将回到自引用循环问题。我会在几分钟内更新我的答案。
  • 优秀;很高兴听到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
相关资源
最近更新 更多