Can Json.NET populate readonly fields in a class?

I have not seen much information about Json.NET that supports deserializing objects using readonly fields. I notice that the .NET DataContract and DataMember attributes allow you to populate readonly fields during deserialization, but Json.NET does not seem to support this, at least from the behavior I see.

+6
source share
3 answers

afai can see that changing the field to readonly results in a null value after deserialization. I had a working sample for another question (modified as shown below), and what behavior I see.

 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); } } 
-2
source share

Not the most elegant solution, but you can extend DefaultConstractResolver to do this:

 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; } } } 

I will simply remove one small check from the CanSetMemberValue method. Unfortunately, this was neither a virtual nor an instance method, so I had to override CreateProperty.

+9
source share

It can be done now. Declare your properties with the JsonProperty attribute and verify that the protected set is declared:

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

This did not work for me when using only get , but works fine with the protected set .

+1
source share

All Articles