No he visto mucha información acerca de Json.NET que admite la deserialización de objetos con campos readonly
. Me doy cuenta de que los atributos .NET DataContract y DataMember permiten rellenar los campos readonly
durante la deserialización, pero Json.NET no parece soportar esto, al menos desde el comportamiento que estoy viendo.¿Puede Json.NET poblar campos de solo lectura en una clase?
Respuesta
afai puede ver el cambio de un campo a readonly
da como resultado un valor de null
después de la deserialización. Tenía una muestra de trabajo para otra pregunta (modificada como se muestra a continuación), y ese es el comportamiento que veo.
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);
}
}
No es la solución más elegante, pero se puede ampliar el DefaultConstractResolver hacerlo:
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;
}
}
}
me acaba de quitar un poco de comprobación del método CanSetMemberValue. Desafortunadamente no es ni un método virtual ni un método de instancia, así que también tuve que anular CreateProperty.
Esto se puede hacer ahora. Declarar sus propiedades con el atributo JsonProperty
, y asegurar que se han declarado un conjunto protegido:
[JsonProperty("Name")] public string Name {get; protected set;}
Esto no funcionó para mí cuando sólo se utiliza un get
, pero funciona perfectamente con el protected set
.
- 1. ¿Puede JAXB crear una propiedad de clase de "solo lectura"?
- 2. Campos de solo lectura en django formset
- 3. Json.NET Serializar miembros privados y no propiedades de solo lectura
- 4. Ignorando campos nulos en Json.net
- 5. Producir una copia de solo lectura de una clase, howto
- 6. Campos de solo lectura en django admin/inline
- 7. ¿Por qué el reafilamiento sugiere campos de solo lectura
- 8. Atributo WCF DataMember para campos de solo lectura?
- 9. Clase C# y miembros de solo lectura
- 10. Orden de campos serializados usando JSON.NET
- 11. administrador de Django: ¿cómo formatear campos de solo lectura?
- 12. Inicializar campos de solo lectura privados después de la Deserialización
- 13. Inicializando una propiedad de solo lectura
- 14. Propiedades de solo lectura de nivel de clase en Python
- 15. Cómo crear dos interfaces para una clase de Java, una de solo lectura, una de lectura y escritura?
- 16. ¿Cómo crear una entidad de solo lectura en Entity Framework?
- 17. Cómo implementar una propiedad de solo lectura
- 18. Solo lectura colección observable
- 19. Hacer que todos los campos de formulario sean de solo lectura en MVC
- 20. Json.NET, no se puede deserializar tipo nulable
- 21. ¿Funciona el uso de campos públicos de solo lectura para estructuras inmutables?
- 22. ¿Cómo puede ser nulo un campo estático de solo lectura?
- 23. Hacer una rama TFS de solo lectura
- 24. Solo lectura de matriz bidimensional en C#
- 25. ¿Alguien puede explicarme esta excepción de solo lectura?
- 26. ¿navegador independiente de solo lectura?
- 27. Escribiendo en una sesión de solo lectura en MVC 3+
- 28. Hacer una propiedad de solo lectura que se pueda escribir en la clase derivada
- 29. Enlazar una DependencyProperty de solo lectura a otra propiedad DependencyProperty
- 30. Editar una vista de solo lectura
Sí, ese es el mismo comportamiento que veo. Desafortunadamente, esto junto con las restricciones del constructor sobre los objetos serializados es el factor decisivo para Json.NET para mí. :( –
Supongo que las clases integradas de .Net tienen acceso privilegiado a esos campos que no están disponibles para la biblioteca de terceros. –
No es diferente de configurar cualquier otro campo con reflejo, por lo que es factible y he archivado un solicitud de función en el rastreador de problemas Json.NET. – asgerhallas