asp.net-web-api json.net utc

asp.net web api - Asp.net WebApi deserializa la cadena de tiempo UTC a la hora local



asp.net-web-api json.net (2)

Aunque ya encontraste una solución para tu pregunta, pensé que podría intentar explicar por qué no funcionó como esperabas.

WebApi utiliza la negociación del tipo de contenido para determinar qué analizador usar al leer datos. Eso significa que mirará el encabezado Content-Type de la solicitud para hacer la determinación. Si el encabezado Content-Type está configurado en application/json , usará Json.Net para analizar el contenido y alimentarlo a su método.

Una solicitud HTTP GET, como la que está realizando aquí, no tiene un tipo de contenido establecido. El "contenido" en este caso es realmente solo la cadena de consulta de la URL. WebApi no espera encontrar datos JSON aquí, por lo que no intentará utilizar un analizador JSON para darle sentido. Incluso si lo hizo, la cadena que está pasando a su método GetAll no es ni siquiera válida JSON. (Tendría que ser citado para ser válido.)

Ahora, si cambiara su método para aceptar una solicitud POST, y configurara el encabezado de tipo de contenido para application/json y pasara la fecha como una cadena JSON en el cuerpo, WebApi usará Json.Net para analizarlo, y funcionará como usted espera.

Por ejemplo, supongamos que tu método se veía así:

[HttpPost] public object GetAll([FromBody]DateTime startDate) { try { return new { StartDate = startDate.ToString("yyyy-MM-dd HH:mm:ss"), StartDateKind = startDate.Kind.ToString(), }; } catch (Exception ex) { return ex.Message; } }

Y usted hizo una solicitud como esta (observe el POST):

POST http://localhost:57524/api/values/GetAll HTTP/1.1 Content-Type: application/json Content-Length: 22 Host: localhost:57524 "1994-11-05T17:15:30Z"

La respuesta sería así:

HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Type: application/json; charset=utf-8 Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Fri, 31 May 2013 01:25:48 GMT Content-Length: 57 {"StartDate":"1994-11-05 17:15:30","StartDateKind":"Utc"}

Como puede ver, reconoce correctamente la fecha para ser UTC en este escenario.

Tengo esta url

http://example.com/api/record/getall?startdate=1994-11-05T17:15:30Z

y este punto final webapi

[ActionName("GetAll")] public object GetAll(DateTime startDate) { ... }

El problema al que me enfrenté es que startDate recibió la cadena deserializada como hora local, " 11/5/1994 9:15:30 AM " en lugar de permanecer en horario UTC, que era lo que quería " 5/11/1994 5:15: 30 PM ".

Estoy usando VS2012 actualización2, el último paquete nuget de Json.net. Sin embargo, si utilizo json.net en una aplicación de consola separada para probar, la misma cadena " 1994-11-05T17: 15: 30Z " puede deserializarse correctamente en " 11/5/1994 5:15:30 PM ".

Alguien sabe lo que está mal aquí?


Si desea modificar la forma en que Asp WebApi analiza los parámetros uri de sus solicitudes GET, puede escribir IModelBinder personalizado de la IModelBinder manera:

public class UtcDateTimeModelBinder : IModelBinder { public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { var stringValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName)?.RawValue as string; DateTime parsedDate; if (!DateTime.TryParse(stringValue, null, DateTimeStyles.AdjustToUniversal, out parsedDate)) { return false; } bindingContext.Model = parsedDate; return true; } }

Y luego anula el encuadernador predeterminado:

GlobalConfiguration.Configure(configuration => configuration.BindParameter(typeof(DateTime), new UtcDateTimeModelBinder()););

Enlace de parámetros en ASP.NET Web API