【问题标题】:JsonConvert.Deserialize appends to default property values. How to prevent this?JsonConvert.Deserialize 附加到默认属性值。如何防止这种情况?
【发布时间】:2020-04-05 21:25:43
【问题描述】:

我有一个 .json 配置文件,我在其中存储应用程序启动时反序列化的应用程序设置。

例子:

{
    "MyProperty1": "MyValue1",
    "MyProperty2": [1, 2, 3]
}

JSON 反序列化的对象是:

public class Config{
    public string MyProperty1{ get; set; }
    public List<int> MyProperty2{ get; set; } = new List<int> { 4, 5, 6 };
}

我遇到的问题是,当属性 MyProperty2 的 JSON 被反序列化时,它会将值 1、2、3 附加到默认属性值 4、5、6,结果是 MyProperty2 = 4 , 5, 6, 1, 2, 3

我希望 MyProperty2 默认为 4、5、6,除非 .json 配置文件中另有指定。任何帮助将不胜感激,谢谢。

【问题讨论】:

  • ObjectCreationHandling.Replace 是谷歌返回的内容
  • 嘿,我显然不能使用谷歌(我试过了)——确实是答案:) 谢谢。如果您想要积分,请发布答案,我会接受。
  • ObjectCreationHandling.Replace 反序列化后的结果是 1,2,3,而不是 OP 想要的 4,5,6
  • 不是 4,5,6,因为 OP 想要 ...我很确定这是 不是真的 因为:我希望 MyProperty2 在 .json 配置文件中默认为 4、5、6除非另有说明
  • 唯一的问题是 json 中的 { "MyProperty2": null }(但它仍然是 在 json 中指定的

标签: c# json serialization properties default-value


【解决方案1】:

根据上述一位 cmet 的回答,并结合我的强迫性要求,即不要留下一个不被接受的答案的问题,特此:

假设变量json包含.json配置文件的内容:

var cfg = JsonConvert.DeserializeObject<Config>(json, new JsonSerializerSettings
{
    ObjectCreationHandling = ObjectCreationHandling.Replace
});

关键是ObjectCreationHandling - 序列化程序设置ObjectCreationHandling.Replace 替换默认值而不是附加到它。

查看更多here

【讨论】:

    【解决方案2】:

    您可以使用JsonConvertNewtonsoft.Json

    var setting = "{\"MyProperty1\": \"MyValue1\", \"MyProperty2\": [1, 2, 3]}";
    var settingConfig = JsonConvert.DeserializeObject(setting);
    

    和配置类

    public class Config
    {
        public string MyProperty1 { get; set; }
        [Newtonsoft.Json.JsonConverter(typeof(DefaultArrayConverter))]
        public List<int> MyProperty2 { get; set; } = new List<int> { 4, 5, 6 };
    }
    

    这里我写了一个客户JsonConverter。

    public class DefaultArrayConverter : JsonConverter
    {
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var value = serializer.Deserialize(reader, objectType);
            return value;
        }
    
        public override bool CanWrite
        {
            get { return false; }
        }
    
        public override bool CanConvert(Type objectType)
        {
            return false;
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    

    它工作正常,但我不确定为什么 MyProperty2 在您的实现中有 6 个值。

    【讨论】:

      【解决方案3】:

      这通常对我有用: 您可能认为如果发出“获取”请求,它将设置默认值。如果在 'get' 之前完成了 'set',则只有在 'value' 为 null 时,该属性才会获得默认值。

      public class Config{
          public string MyProperty1{ get; set; }
      
          private List<int> myProperty2{ get; set; } ;
          public List<int> MyProperty2{ 
              get{
                  if (myProperty2 == null)
                      myProperty2 = new List<int> { 4, 5, 6 };
      
                  return  myProperty2 ;
              } 
              set{
                  myProperty2 = value;
              } 
          } 
      }
      

      【讨论】:

      • 我同意,这是解决问题的漫长道路 :) 但是,正如 @Selvin 上面提到的,使用 JsonConvert 设置 ObjectCreationHandling.Replace 将解决我遇到的问题。
      【解决方案4】:

      尝试解决 Config 类中的所有问题:

      public class Config
      {
          public Config()
          {
              this.MyProperty2 = new List<int> { 4, 5, 6 };
          }
          public string MyProperty1 { get; set; }
          public List<int> MyProperty2 {
              get {
                  return this.MyProperty2;
              } 
              set {
                  if(this.MyProperty2.Count > 0)
                  {
                      this.MyProperty2.Clear();
                      this.MyProperty2 = value;
                  }
              } 
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-10-16
        • 2023-04-03
        • 1970-01-01
        • 1970-01-01
        • 2020-03-18
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多