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

C# 调用JsonConvert.SerializeObject时,如何转换编码的JSON字符串属性?,c#,json,json.net,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

我有一个带有一些字符串属性的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 = actionExecutedContext.Response?.Content?.ReadAsStringAsync().Result
我包含这行代码,以演示正在使用一个方法设置属性–
ReadAsStringAsync
,该方法返回一个编码的JSON字符串。在我的例子中,它将始终是一个编码的JSON字符串,或者它将是空的


想法?

您可以通过将converter属性置于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);
  }
}

@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);
        }
    }
//
///RawJsonConverter用于转换包含有效字符串编码的对象的字符串类型属性
///将JavaScript对象表示法(JSON)转换为非编码字符串,以便将其视为JSON对象和
///序列化数组而不是字符串的包含对象时。
///请注意,对象的属性必须用JSONConverterateAttribute修饰,如下所示:
///[JsonConverter(类型(RawJsonConverter))]
///公共字符串EncodedJsonProperty{get;set;}
/// 
公共类RawJsonConverter:JsonConverter
{
/// 
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
尝试
{
var value=serializer.Deserialize(reader.Trim();
返回JToken.Parse(value.ToString();
}
捕获(例外情况除外)
{
抛出新异常(“无法从RawJsonConverter中的字符串解析JSON。”,ex);
}
}
/// 
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
writer.WriteRawValue((字符串)值);
}
/// 
公共覆盖布尔CanConvert(类型objectType)
{
返回objectType==typeof(字符串);
}
}

对JSON数据使用JRaw类型而不是字符串。我不能这样做。我使用这个类作为实体框架中的实体。如果有属性的话,我也不介意