调用JsonConvert.SerializeObject时如何转换编码的JSON字符串属性?

时间:2018-08-22 21:49:10

标签: c# json json.net

我有一个POCO,它的一些字符串属性包含编码的JSON对象。

当我调用JsonConvert.SerializeObject时,我想将这些字符串转换回JSON,并让Json.NET将它们序列化为嵌入式JSON对象。

调用JsonConvert.SerializeObject时如何转换编码的JSON字符串属性?

以下是相关代码:

public class LogAction
{
    // other properties
    public string Request { get; set; }
    public string Response { get; set; }
}

下面是设置Response属性的代码行:

Response = actionExecutedContext.Response?.Content?.ReadAsStringAsync().Result

我包括以下代码行,以演示使用方法ReadAsStringAsync设置属性,该方法返回编码的JSON字符串。就我而言,它将始终是编码的JSON字符串,或者将为null。

想法?

2 个答案:

答案 0 :(得分:2)

您可以通过将转换器属性放在JSON属性上方来使用特定于属性的转换器:

public class LogAction
{
  // other properties
  [JsonConverter(typeof(RawJsonConverter))]
  public string Request { get; set; }
  [JsonConverter(typeof(RawJsonConverter))]
  public string Response { get; set; }
}

转换器将如下,并假设它们已经是JSON来编写字符串。

public class RawJsonConverter: JsonConverter
{
  public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  {
    return JObject.Load(reader).ToString();
  }

  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  {
    writer.WriteRawValue((string)value);
  }

  public override bool CanConvert(Type objectType)
  {
    return objectType == typeof(string);
  }
}

答案 1 :(得分:0)

@ckuri使我走上了正确的道路,因此我将他的回答标记为答案,但最终我决定采用其他实现。

这就是我更改实现的原因:

  • 编码的字符串可以是一个对象,也可以是一个数组。
  • 如果编码的字符串属性无法显示,我希望得到清晰的错误消息 被解析。
  • 使用JToken.Load(reader)调用时,我看到了一些缓冲区溢出问题。

我希望这会对其他人有所帮助。

    /// <summary>
    /// The RawJsonConverter is used to convert an object's string-typed properties containing valid string-encoded
    /// JavaScript Object Notation (JSON) into non-encoded strings so that they may be treated as JSON objects and
    /// arrays instead of strings when their containing objects are serialized.
    /// Note that the properties of the object must be decorated with the JsonConverterAttribute like this:
    ///     [JsonConverter(typeof(RawJsonConverter))]
    ///     public string EncodedJsonProperty { get; set; }
    /// </summary>
    public class RawJsonConverter : JsonConverter
    {
        /// <inheritdoc />
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            try
            {
                var value = serializer.Deserialize<String>(reader).Trim();
                return JToken.Parse(value).ToString();
            }
            catch (Exception ex)
            {
                throw new Exception("Could not parse JSON from string in RawJsonConverter.", ex);
            }
        }

        /// <inheritdoc />
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteRawValue((string)value);
        }

        /// <inheritdoc />
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(string);
        }
    }