c# - Especificar un formato personalizado de DateTime al serializar con Json.Net
asp.net-web-api (5)
Estoy desarrollando una API para exponer algunos datos mediante ASP.NET Web API.
En una de las API, el cliente quiere que expongamos la fecha en el formato yyyy-MM-dd
. No quiero cambiar la configuración global (por ejemplo, GlobalConfiguration.Configuration.Formatters.JsonFormatter
) para eso, ya que es muy específico para este cliente. Y lo desarrollo en una solución para múltiples clientes.
Una de las soluciones que podría pensar es crear un JsonConverter
personalizado y luego ponerlo en la propiedad que necesito para hacer el formateo personalizado
p.ej
class ReturnObjectA
{
[JsonConverter(typeof(CustomDateTimeConverter))]
public DateTime ReturnDate { get;set;}
}
Me pregunto si hay alguna otra manera fácil de hacerlo.
Estás en el camino correcto. Como dijo que no puede modificar la configuración global, la siguiente mejor JsonConverter
es aplicar el atributo JsonConverter
a medida que lo necesite, como sugirió. Resulta que Json.Net ya tiene incorporado IsoDateTimeConverter
que le permite especificar el formato de fecha. Desafortunadamente, no puede establecer el formato a través del atributo JsonConverter
, ya que el único argumento del atributo es un tipo. Sin embargo, hay una solución simple: subclase IsoDateTimeConverter
, luego especifique el formato de fecha en el constructor de la subclase. Aplique el atributo JsonConverter
donde sea necesario, especificando su convertidor personalizado y listo. Aquí está la totalidad del código necesario:
class CustomDateTimeConverter : IsoDateTimeConverter
{
public CustomDateTimeConverter()
{
base.DateTimeFormat = "yyyy-MM-dd";
}
}
Si no te importa tener el tiempo allí también, ni siquiera necesitas subclasificar el IsoDateTimeConverter. Su formato de fecha predeterminado es yyyy''-''MM''-''dd''T''HH'':''mm'':''ss.FFFFFFFK
(como se ve en el código fuente ).
Puedes usar este enfoque:
public class DateFormatConverter : IsoDateTimeConverter
{
public DateFormatConverter(string format)
{
DateTimeFormat = format;
}
}
Y úsalo de esta manera:
class ReturnObjectA
{
[JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd")]
public DateTime ReturnDate { get;set;}
}
La cadena DateTimeFormat utiliza la sintaxis de cadena de formato .NET que se describe aquí: https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
También disponible usando una de las sobrecargas de configuración del serializador:
var json = JsonConvert.SerializeObject(someObject, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });
O
var json = JsonConvert.SerializeObject(someObject, Formatting.Indented, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });
Las sobrecargas que toman un tipo también están disponibles.
También se puede hacer con una instancia de IsoDateTimeConverter
temporal, sin cambiar la configuración de formato global:
string json = JsonConvert.SerializeObject(yourObject,
new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });
Esto usa la sobrecarga que toma un params JsonConverter[]
argumento.
Cree una clase auxiliar y aplíquela a su atributo de propiedad
Clase de ayuda:
public class ESDateTimeConverter : IsoDateTimeConverter
{
public ESDateTimeConverter()
{
base.DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
}
}
Tu código usa así:
[JsonConverter(typeof(ESDateTimeConverter))]
public DateTime timestamp { get; set; }