newtonsoft - objetos dinamicos c#
Usando Json.NET, ¿cómo puedo analizar una lista de objetos con nombres dinámicos en una lista? (2)
Incluso hay otro enfoque: puedes usar objetos de expansión :
dynamic response = JsonConvert.DeserializeObject<ExpandoObject>("JSON TEXT", new ExpandoObjectConverter());
Y puede acceder a las propiedades usando el tipado dinámico:
long someValue = [email protected]_1.values.value;
Además, dado que ExpandoObject
implementa IDictionary<string, object>
, puede usarlo como un diccionario y verificar si existe una propiedad:
if(((IDictionary<string, object>)response.@object).ContainsKey("property_1"))
{
}
¡Parece que vas a ahorrar mucho tiempo yendo de esta manera!
Respondiendo odio en esta respuesta
Parece que el mayor odio en mi respuesta se centra en este comentario @EZI:
Y supongamos que no conoce property_14 antes de deserializar el json ..
Y el otro que responde @LB argumenta esto en su propia respuesta:
Pero este enfoque requeriría que usted sepa que property_14 será devuelto por su servidor de antemano ...
En mi caso, me parece que esta preocupación ya se abordó en mi respuesta cuando menciono que ExpandoObject
implementa IDictionary<string, object>
. Quizás no sepa que property_14
formará parte del gráfico de objeto deserializado. No hay problema
if(((IDictionary<string, object>)response.@object).ContainsKey("property_14"))
{
// You''ve already addressed the issue, because you won''t get a
// run-time exception since you''ll access such property if it''s already
// in the returned response...
object property_14 = [email protected]_14;
}
A continuación se muestra un ejemplo del formato JSON que recibo de una API externa:
"object": {
"property_1": {
"values": {
"value": 1,
"displayValue": "1"
}
},
"property_5": {
"values": {
"value": 3,
"displayValue": "3"
}
},
"property_8": {
"values": {
"value": 1,
"displayValue": "1"
}
},
"property_14": {
"values": {
"value": 392,
"displayValue": "392.0"
}
},
"property_17": {
"values": {
"value": 14,
"displayValue": "14"
}
}
}
Hay alrededor de 100 tipos de propiedades diferentes que se pueden enviar, pero todos siguen la misma estructura. La única distinción es el nombre de la propiedad ("property_1", "property_5", etc.). En lugar de intentar escribir una clase con una larga lista de propiedades que no siempre se usan, creo que sería mucho más útil analizar esto en una lista de objetos, usando el nombre de la propiedad en la clase resultante de esta manera:
public class Property
{
public string Name { get; set; }
public PropertyValues Values { get; set; }
}
public class PropertyValues
{
public double Value { get; set; }
public string DisplayValue { get; set; }
}
En este caso, el nombre de propiedad ("propiedad_1", "propiedad_5", etc.) se asignaría al campo Nombre del objeto Propiedad.
¿Cómo se puede lograr esto usando Json.NET?
var result = JsonConvert.DeserializeObject<Root>(json);
Tu modelo está abajo
public class Root
{
public Dictionary<string, ValueWrapper> Object { get; set; }
}
public class ValueWrapper
{
public PropertyValues Values { get; set; }
}
public class PropertyValues
{
public int Value { get; set; }
public string DisplayValue { get; set; }
}
Por cierto: Json.Net puede manejar dinámicas más fácilmente que las propuestas por @ MatíasFidemraizer ...
var val = ((dynamic)JsonConvert.DeserializeObject(jsonstring))
[email protected]_14.values.value;
var val = ((dynamic)JsonConvert.DeserializeObject(jsonstring))
.@object["property_14"].values.value;
Pero este enfoque requeriría que usted sepa que property_14
será devuelto por su servidor de antemano ...