我没有看到很多关于Json.NET支持使用readonly
字段反序列化对象的信息。我注意到.NET DataContract和DataMember属性允许在反序列化期间填充readonly
字段,但Json.NET似乎不支持这一点,至少从我看到的行为来看。
答案 0 :(得分:9)
不是最优雅的解决方案,但您可以扩展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。
答案 1 :(得分:2)
现在可以这样做了。使用JsonProperty
属性声明属性,并确保它们具有声明的受保护集:
[JsonProperty("Name")] public string Name {get; protected set;}
仅使用get
时,这对我不起作用,但与protected set
完美配合。
答案 2 :(得分:-2)
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);
}
}