简体   繁体   English

C# 如何将嵌套的 JSON 的一部分保存到 object 属性中,但不反序列化?

[英]C# How to save part of nested JSON into object property, but not deserialized?

This is my JSON这是我的 JSON

{
    "type": "user_settings",
    "created_at": 1610973280043,
    "data": {
        "user_id": 12345,
        "updated_at": "2021-01-18T15:34:40+03:00"
    }
}

These are my classes:这些是我的课:

public class BaseMessage
{
    [JsonProperty("type")]
    public string Type { get; set; }

    [JsonProperty("created_at")]
    public long CreatedAt { get; set; }

    [JsonProperty("data")]
    public DataDTO Data { get; set; }

    public string DataJson {get; set;} // <-- Here I need string like this "{ "user_id": 12345, "updated_at": "2021-01-18T15:34:40+03:00" }"
}

public class DataDTO
{
    [JsonProperty("user_id")]
    public int UserId { get; set; }

    [JsonProperty("updated_at")]
    public DateTime? UpdatedAt { get; set; }
}

So I need parsed "data" (it works ok) and save nested JSON as a string (I don't know how).所以我需要解析“数据”(它工作正常)并将嵌套的 JSON 保存为字符串(我不知道如何)。 Is there elegant way to save nested JSON into string property?有没有优雅的方法将嵌套的 JSON 保存到字符串属性中?

Something like this:像这样的东西:

public class BaseMessage
{
    [JsonProperty("type")]
    public string Type { get; set; }

    [JsonProperty("created_at")]
    public long CreatedAt { get; set; }

    [JsonProperty("data")]
    public DataDTO Data { get; set; }

    [JsonPropertyAsString("data")] // <-- This is my fantasy :)
    public string DataJson {get; set; }
}

As @dbc commented you can create a custom JsonConverter for the DataJson property, but you also should do something with your another property which is mapped from the data JSON field - Data of DataDTO type.正如@dbc 评论的那样,您可以为DataJson属性创建自定义JsonConverter ,但您还应该对从data JSON 字段映射的另一个属性执行某些操作 - DataDTO类型的Data I can propose the following solution:我可以提出以下解决方案:

1. Custom JSON Converter (I took this from @dbc's answer ) 1. 自定义 JSON 转换器(我从@dbc的回答中得到这个)

public class RawConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
       if (reader.TokenType == JsonToken.Null)
          return null;
       var raw = JRaw.Create(reader);
       return raw.ToString();
    }

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

2. Decorate your DataJson property with the JsonConverter attribute and remove JsonPropertyAttribute for the Data property 2. 使用DataJson属性装饰您的JsonConverter属性并删除Data属性的JsonPropertyAttribute

Note that if you don't remove the JsonPropertyAttribute then it won't work, since you have two properties which are mapped from the same JSON field, and as I know this is not supported by Json.NET by default.请注意,如果您不删除JsonPropertyAttribute那么它将不起作用,因为您有两个属性是从同一个 JSON 字段映射的,据我所知,默认情况下 Json.NET 不支持此功能。

public class BaseMessage
{
   [JsonProperty("type")]
   public string Type { get; set; }

   [JsonProperty("created_at")]
   public long CreatedAt { get; set; }

   public DataDTO Data { get; set; }

   [JsonProperty("data")]
   [JsonConverter(typeof(RawConverter))]
   public string DataJson {get; set;}
}

3. Update your BaseMessage class so this calculates the value of the Data property from DataJson 3. 更新您的BaseMessage class 以便从DataJson计算Data属性的值

public class BaseMessage
{
   private DataDTO data;

   [JsonProperty("type")]
   public string Type { get; set; }

   [JsonProperty("created_at")]
   public long CreatedAt { get; set; }

   public DataDTO Data
   {
       if (data == null)
       {
          data = JsonConvert.DeserializeObject<DataDTO>(DataJson);
       }
       return data;
   }

   [JsonProperty("data")]
   [JsonConverter(typeof(RawConverter))]
   public string DataJson {get; set;}
}

Note that I believe this is not the best solution and sure that there are other much better alternatives, but it might be feasible in your case.请注意,我认为这不是最好的解决方案,并且肯定还有其他更好的选择,但在您的情况下它可能是可行的。

Do you mean to use this??你的意思是用这个??

var data = Newtonsoft.Json.JsonConvert.SerializeObject(object); var 数据 = Newtonsoft.Json.JsonConvert.SerializeObject(object);

if yes, install the newtonSoft packge.如果是,请安装 newtonSoft 软件包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM