Sé que hay un atributo para manejar los establecedores privados, pero quiero este comportamiento como predeterminado, ¿hay alguna manera de lograrlo? Excepto modificar la fuente. Sería genial si hubiera un escenario para esto.
Vine aquí buscando el atributo real que hace que Json.NET llene una propiedad de solo lectura al deserializar, y eso es simplemente [JsonProperty], por ejemplo:
var settings =newJsonSerializerSettings{ContractResolver=newPrivateSetterContractResolver()};var model =JsonConvert.DeserializeObject<Model>(json, settings);
La opción de serialización predeterminada admite todos los tipos de miembros de clase. Por lo tanto, esta solución devolverá todos los tipos de miembros privados, incluidos los campos. Solo me interesa apoyar también a los setters privados.
Alt2: Cree un ContractResolver personalizado:
Por lo tanto, estas son las mejores opciones, ya que solo verificamos las propiedades.
Parece que Alt 2 es definitivamente el camino a seguir hoy en día. DefaultMembersSearchFlagsha quedado obsoleto .
Todd Menier
4
Con c # 6, {get; }NO es equivalente a { get; private set; }. Por la primera vía property.GetSetMethod(true)regresa nully la segunda true. Esto me sorprendió. Debe tener private set;para que la deserialización funcione como se esperaba.
La respuesta de @ Daniel (Alt2) es acertada, pero necesitaba que esto funcionara tanto para los establecedores privados como para los captadores (estoy trabajando con una API que en realidad tiene algunas cosas de solo escritura, como user.password). Esto es lo que terminé con:
Respuestas:
Vine aquí buscando el atributo real que hace que Json.NET llene una propiedad de solo lectura al deserializar, y eso es simplemente
[JsonProperty]
, por ejemplo:Solución alternativa
Simplemente proporcione un constructor que tenga un parámetro que coincida con su propiedad:
Ahora esto funciona:
Prefiero este enfoque siempre que sea posible ya que:
{ get; private set; }
y solo{ get; }
.fuente
{get;private set;}
, no con{get;}
{ get; }
si el tipo tiene un constructor con un parámetro que coincide con el nombre de la propiedad.Nueva respuesta actualizada
Escribí una distribución de origen NuGet para esto, que instala un solo archivo con dos solucionadores de contratos personalizados:
Instale NuGet:
Entonces solo usa cualquiera de los resolutores:
Puede leer sobre esto aquí: http://danielwertheim.se/json-net-private-setters-nuget/
Repositorio de GitHub: https://github.com/danielwertheim/jsonnet-privatesetterscontractresolvers
Respuesta anterior (aún válida)
Hay dos alternativas que pueden solucionar el problema.
Alt 1: en los deserializadores
La opción de serialización predeterminada admite todos los tipos de miembros de clase. Por lo tanto, esta solución devolverá todos los tipos de miembros privados, incluidos los campos. Solo me interesa apoyar también a los setters privados.
Alt2: Cree un ContractResolver personalizado:
Por lo tanto, estas son las mejores opciones, ya que solo verificamos las propiedades.
Para obtener más información, lea mi publicación: http://danielwertheim.se/json-net-private-setters/
fuente
DefaultMembersSearchFlags
ha quedado obsoleto .{get; }
NO es equivalente a{ get; private set; }
. Por la primera víaproperty.GetSetMethod(true)
regresanull
y la segundatrue
. Esto me sorprendió. Debe tenerprivate set;
para que la deserialización funcione como se esperaba.La respuesta de @ Daniel (Alt2) es acertada, pero necesitaba que esto funcionara tanto para los establecedores privados como para los captadores (estoy trabajando con una API que en realidad tiene algunas cosas de solo escritura, como
user.password
). Esto es lo que terminé con:Registrado así:
fuente