【问题标题】:Can Json.NET populate readonly fields in a class?Json.NET 可以填充类中的只读字段吗?
【发布时间】:2010-11-14 19:01:46
【问题描述】:

我没有看到太多关于 Json.NET 支持使用 readonly 字段反序列化对象的信息。我确实注意到 .NET DataContract 和 DataMember 属性允许在反序列化期间填充 readonly 字段,但 Json.NET 似乎不支持这一点,至少从我看到的行为来看。

【问题讨论】:

    标签: .net json.net


    【解决方案1】:

    不是最优雅的解决方案,但您可以扩展 DefaultConstractResolver 来做到这一点:

    public class ContractResolver : DefaultContractResolver
    {
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            var property = base.CreateProperty(member, memberSerialization);
            property.Writable = CanSetMemberValue(member, true);
            return property;
        }
    
        public static bool CanSetMemberValue(MemberInfo member, bool nonPublic)
        {
            switch (member.MemberType)
            {
                case MemberTypes.Field:
                    var fieldInfo = (FieldInfo)member;
    
                    return nonPublic || fieldInfo.IsPublic;
                case MemberTypes.Property:
                    var propertyInfo = (PropertyInfo)member;
    
                    if (!propertyInfo.CanWrite)
                        return false;
                    if (nonPublic)
                        return true;
                    return (propertyInfo.GetSetMethod(nonPublic) != null);
                default:
                    return false;
            }
        }
    }
    

    我刚刚从 CanSetMemberValue 方法中删除了一个小检查。不幸的是,它既不是虚拟方法也不是实例方法,所以我也不得不重写 CreateProperty。

    【讨论】:

      【解决方案2】:

      现在可以完成了。使用 JsonProperty 属性声明您的属性,并确保它们声明了受保护的集:

      [JsonProperty("Name")] public string Name {get; protected set;}
      

      仅使用 get 时,这对我不起作用,但与 protected set 完美搭配。

      【讨论】:

      • 此功能不需要[JsonProperty] 属性
      • 它在 2017 年对我没有任何效果。我几乎尝试了我能想到的所有组合。我正在编写一个代码生成器,所以我花了很多时间使生成的代码尽可能紧凑。但这肯定在过去两年中发生了变化。
      【解决方案3】:

      afai 可以看到将字段更改为 readonly 会在反序列化后产生 null 值。我有另一个问题的工作示例(修改如下所示),这就是我看到的行为。

      public class NameAndId
      {
          public string name;
          public int id; 
      }
      
      public class Data
      {
          public NameAndId[] data;
      }
      
      public class Target
      {
          public string id;
          public readonly NameAndId from;
          public DateTime updated_time;
          public readonly string message;
          public Data likes;
      }
      
      public class Program
      {
          static void Main(string[] args)
          {
              string json = File.ReadAllText(@"c:\temp\json.txt");
              Target newTarget = JsonConvert.DeserializeObject<Target>(json);
          }
      }
      

      【讨论】:

      • 是的,这与我看到的行为相同。不幸的是,这以及对序列化对象的构造函数限制对我来说是 Json.NET 的交易破坏者。 :(
      • 我的猜测是 .Net 内置类对第三方库不可用的那些字段具有特权访问权限。
      • 这与使用反射设置任何其他字段没有什么不同,所以它是可行的,我已经在 J​​son.NET 问题跟踪器上提交了一个功能请求。
      • @MarkLeMoine 实际上 - 据我所知 - 没有 ctor 限制是您无法通过创建自定义合同解析器来解决的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-19
      • 2019-04-14
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      相关资源
      最近更新 更多