serialize restful net formato convert json datetime asp.net-web-api model-binding

restful - json net datetime format



Pasar UTC DateTime a API web Resultados del método HttpGet en hora local (3)

Estoy tratando de pasar una fecha UTC como un parámetro de cadena de consulta a un método de API web. La URL se ve como

/api/order?endDate=2014-04-01T00:00:00Z&zoneId=4

La firma del método parece

[HttpGet] public object Index(int zoneId, DateTime? endDate = null)

La fecha 31/03/2014 8:00:00 PM pero me gustaría que entre como 01/04/2014 12:00:00 AM

Mi JsonFormatter.SerializerSettings parece a esto

new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), DateTimeZoneHandling = DateTimeZoneHandling.Utc, DateFormatHandling = DateFormatHandling.IsoDateFormat };

EDIT # 1: Me di cuenta cuando 2014-04-01T00:00:00Z se serializará al tipo UTC DateTime en C #. Sin embargo, he encontrado una endDate.Value.ToUniversalTime() hacer endDate.Value.ToUniversalTime() para convertirlo aunque me parece extraño cómo funciona para un POST pero no para un GET.


El valor del parámetro de cadena de consulta que está enviando 2014-04-01T00:00:00Z es la hora UTC. Por lo tanto, lo mismo se traduce a una hora basada en su reloj local y si llama a ToUniversalTime() , se convierte de nuevo a UTC.

Entonces, ¿cuál es exactamente la pregunta? Si la pregunta es por qué sucede esto si se envía como cadena de consulta pero no cuando se publica en el cuerpo de la solicitud, la respuesta a esa pregunta es que ASP.NET Web API vincula la ruta URI, cadena de consulta, etc. usando el enlace de modelo y el cuerpo usando enlace de parámetros . Para el último, usa un formateador de medios. Si envía JSON, se utiliza el formateador de medios JSON y está basado en JSON.NET.

Como ha especificado DateTimeZoneHandling.Utc , usa esa configuración y obtiene el tipo de fecha y hora que desee. Por cierto, si cambia esta configuración a DateTimeZoneHandling.Local , entonces verá el mismo comportamiento que el enlace del modelo.


Si desea que la conversión sea transparente, puede usar un TypeConverter personalizado:

public sealed class UtcDateTimeConverter : DateTimeConverter { public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { return ((DateTime)base.ConvertFrom(context, culture, value)).ToUniversalTime(); } }

y conectarlo usando:

TypeDescriptor.AddAttributes(typeof(DateTime), new TypeConverterAttribute(typeof(UtcDateTimeConverter)));

A continuación, el parámetro de cadena de consulta se instanciará como DateTimeKind.Utc .


Terminé usando el método ToUniversalTime() medida que entran los parámetros.