newtonsoft - serialize json to object c#
¿Cómo puedo agregar un nodo raíz personalizado al serializar un objeto con JSON.NET? (4)
He agregado una propiedad personalizada a algunos de mis objetos como este:
[JsonCustomRoot("status")]
public class StatusDTO
{
public int StatusId { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
}
El atributo es muy simple:
public class JsonCustomRoot :Attribute
{
public string rootName { get; set; }
public JsonCustomRoot(string rootName)
{
this.rootName = rootName;
}
}
El resultado predeterminado de JSON.NET al serializar una instancia de un objeto es este:
{"StatusId":70,"Name":"Closed","Created":"2012-12-12T11:50:56.6207193Z"}
Ahora la pregunta es: ¿cómo puedo agregar un nodo raíz al JSON con el valor del atributo personalizado como sigue ?
{status:{"StatusId":70,"Name":"Closed","Created":"2012-12-12T11:50:56.6207193Z"}}
He encontrado varios artículos que mencionan la interfaz IContractResolver , pero no puedo entender cómo hacerlo. Mis intentos incluyen esta pieza de código inacabada:
protected override JsonObjectContract CreateObjectContract(Type objectType)
{
JsonObjectContract contract = base.CreateObjectContract(objectType);
var info = objectType.GetCustomAttributes()
.SingleOrDefault(t => (Type)t.TypeId==typeof(JsonCustomRoot));
if (info != null)
{
var myAttribute = (JsonCustomRoot)info;
// How can i add myAttribute.rootName to the root from here?
// Maybe some other method should be overrided instead?
}
return contract;
}
¿Qué pasa si usas un objeto anónimo?
JSON.Serialize(new { status = targetObject});
Aquí hay una solución específica para Web API, que también estoy usando: RootFormatter.cs
Lo escribí en base a la creación de un formateador JSONP para ASP.NET Web API .
En lugar de usar un atributo personalizado, estoy reutilizando el campo Título de JsonObjectAttribute
. Aquí hay un código de uso:
using Newtonsoft.Json
[JsonObject(Title = "user")]
public class User
{
public string mail { get; set; }
}
Luego, agregue RootFormatter a su App_Start y regístrelo de la siguiente manera en WebApiConfig
:
GlobalConfiguration.Configuration.Formatters.Insert(0, new RootFormatter());
Pude obtener una respuesta envolvente similar a WebMessageBodyStyle.Wrapped
de WCF. WebMessageBodyStyle.Wrapped
:
{"user":{
"mail": "[email protected]"
}}
Una manera muy fácil de abordar esto es colocar el objeto dentro de otro objeto. quizás fue demasiado simplista mirarlo, pero funciona cuando se trabaja con colecciones y objetos singulares.
public class StatusDTO
{
public int StatusId { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
}
public class statusJasonModel
{
public StatusDTO status { get; set; }
}
Ahora, si coloca el StatusDTO dentro del objeto statusJsonModel y lo serializa como Json. Debería darte la respuesta deseada.
Tuve un desafío similar en uno de mis proyectos. A continuación se muestra el paso que tomé para resolver el problema.
1. Mi clase de Entidad
public class Product
{
[Key]
public string Id { get; set; }
public string Title { get; set; }
public string Album { get; set; }
public string Artist { get; set; }
public string Genre { get; set; }
}
2. Creó otra Clase, que se define en esta forma.
public class KindOfMedia
{
public KindOfMedia()
{
Product = new List<Product>();
}
public List<Product> Product { get; set; }
}
3. El controlador de API web, que devolverá json
public HttpResponseMessage Products()
{
var kind = new KindOfMedia();
kind.Products = new List<Product>();
kind.Products.Add(new Product
{
Id = Guid.NewGuid().ToString(),
Title = "I am A Winner",
Album = "",
Artist = "Project Fame",
Genre = "Contemporal"
});
kind.Products.Add(new Product
{
Id = Guid.NewGuid().ToString(),
Title = "Great Nation",
Album = "Oceans",
Artist = "Timi Dakolo",
Genre = "Gospel"
});
return Request.CreateResponse(HttpStatusCode.OK, kind);
}
4. Agregue esta línea de código a mi archivo de configuración de WebApi en la carpeta App_Start
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
tenga en cuenta que Newtonsoft.Json.PreserveReferencesHandling.None no conservará la referencia del tipo de serialización
El Json resultante es
{
"Musics": [
{
"Id": "bf9faeee-7c39-4c33-a0ea-f60333604061",
"Title": "I am A Winner",
"Album": "",
"Artist": "Project Fame",
"Genre": "Contemporal"
},
{
"Id": "243edd32-7ba2-4ac4-8ab9-bba6399cb0a6",
"Title": "Great Nation",
"Album": "Oceans",
"Artist": "Timi Dakolo",
"Genre": "Gospel"
}
]
}