【问题标题】:Deserialize a string field into a property object将字符串字段反序列化为属性对象
【发布时间】:2020-08-17 06:16:07
【问题描述】:

假设我有一个 MyClass 类型的对象,它被序列化为 Json,如下所示:

{"DurationField":"3 Months", *OtherProperties*}

我想把这个 Json 反序列化成下面的类:

public class MyClass{
  *OTHER PROPERTIES*

  public Duration DurationField{ get; set;}
}

public class Duration{
  public Duration()

  // Constructor that takes a string, parses it and sets Units and N
  public Duration(string strValue){
  Duration duration = Duration.Parse(strValue)
  N = duration.N;
  Units = duration.Units;
}

  // private method that takes a string and returns a Duration
  private Duration Parse(string str){
   ...
}

  // Enum field to represent units of time, like day/month/year
  public TimeUnits Units{ get; set;}

  // Number of units of time
  public int N{ get; set;}

}

我试图实现一个自定义的 JsonConverter(如下),只是意识到它只能在“DurationField”的子节点上工作,这意味着我必须将它序列化为“DurationField”:{“Value ": "3 Months"} 或类似的东西。

public sealed class DurationConverter : JsonConverter<Duration>
  {
    public override bool CanConvert(Type objectType)
    {
      return (objectType == typeof(Duration));
    }

    public override Duration Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
      // Load the JSON for the Result into a JObject
      JObject jo = JObject.Parse(reader.GetString());

      // Read the properties which will be used as constructor parameters
      string durationString = (string)jo["DurationField"];

      // Construct the Result object using the non-default constructor
      Duration result = new Duration(tenorString);

      // (If anything else needs to be populated on the result object, do that here)

      // Return the result
      return result;
    }


    public override void Write(Utf8JsonWriter writer, Duration value, JsonSerializerOptions options)
    {
      JsonSerializer.Serialize(writer, value, options);
    }
  }

有没有办法解决这个问题?即,让自定义转换器将字符串作为输入,并在解析字符串后将其转换为对象?我能想到的最接近的就是 JsonStringEnumConverter,它接受一个字符串并将其转换为一个 Enum。

【问题讨论】:

  • 为什么要混合使用Newtonsoft.JSONSystem.Text.Json API?

标签: c# json deserialization system.text.json jsonconverter


【解决方案1】:

我知道这不是您所要求的,但解决此问题的一种方法可能是:

public class MyClass{
  *OTHER PROPERTIES*

  public string DurationField { get; set;}
  private Duration _duration = null;

  [JsonIgnore]
  public Duration Duration {
    get {
      if (_duration == null) {
        _duration = new Duration(this.DurationField);
      }

      return _duration;
    }
  }
}

这允许您保留原始字符串值,以防它无法正确解析等,还可以让您访问您的Duration

【讨论】:

    猜你喜欢
    • 2017-05-03
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多