¿Cuál es la mejor manera de detectar una solicitud JSON en ASP.NET?

La mayoría de los frameworks ajax parecen estandarizarse con “X-Request-With” en un encabezado o en la cadena de consulta.

Y en ASP.NET MVC puedes usar el método de extensión

Request.IsAjaxRequest() 

Debido a que un cliente ajax puede solicitar varios tipos de contenido diferentes, no solo “application / json” ex: “application / xml”.

Estoy usando el siguiente método de código / extensión de código, pero me encantaría ver qué están haciendo los demás o si hay algo que me perdí o una forma mejor.

 public static bool IsJsonRequest(this HttpRequestBase request) { return request.Headers["Accept"].Split(',') .Any(t => t.Equals("application/json", StringComparison.OrdinalIgnoreCase)); } 

Gracias por adelantado.

¿Por qué no puede simplemente pasar una variable bool decir IsJsonRequest del cliente donde está haciendo la solicitud?

Luego haga un chequeo en el método de acción.

o

Podría usar el encabezado de aceptación de la solicitud para esto. Esto indica el tipo de contenido que el cliente desea que el servidor le envíe.

Debería utilizar el encabezado de aceptación de la solicitud para esto. Esto indica el tipo de contenido que el cliente desea que el servidor le envíe.

No utilice el encabezado de tipo de contenido de la solicitud: esto indica que es el tipo de cuerpo del mensaje de solicitud . Por todos los medios, configúrelo en “application / json” si está POSTING o PUTeando algunos Json en el servidor, pero si está realizando una solicitud GET, el tipo de contenido debe estar vacío (ya que el cuerpo de una solicitud GET está vacío), y si está publicando un formulario de varias partes o algo más, entonces debe reflejar ese tipo.

El comportamiento de los formularios en la web es establecer el tipo de contenido de la solicitud en ‘multipart / form-data’ y el tipo de aceptación en ‘text / html’. En la web, sobrecargar el servidor para que devuelva el mismo tipo que el tipo de contenido de la solicitud mientras ignora el encabezado del tipo de aceptación significaría que los formularios publicados devuelven datos de formulario codificados en lugar de una página html. Obviamente, este no es el comportamiento correcto, así que no cree sus aplicaciones en torno a una interpretación de este tipo del contenido de la solicitud.

Me pareció muy útil la respuesta de Pete Kirkham . Y creo que eso debería marcarse como solución.

Este es mi código de acuerdo a ello:

 ///  /// Determines whether the request is a Json Request ///  public static bool GetIsJsonRequest(HttpRequest request) { if (request == null) { throw new ArgumentNullException("request"); } bool rtn = false; const string jsonMime = "application/json"; if (request.AcceptTypes!=null) { rtn = request.AcceptTypes.Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase)); } return rtn || request.ContentType.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries).Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase)); } 

—ACTUALIZAR—

Siguiendo la sugerencia de @Mvision, esta es la versión MVC:

 public static bool GetIsJsonRequest(HttpRequestBase request) { if (request == null) { throw new ArgumentNullException("request"); } bool rtn = false; const string jsonMime = "application/json"; if (request.AcceptTypes!=null) { rtn = request.AcceptTypes.Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase)); } return rtn || request.ContentType.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries).Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase)); } 

Si necesita usar este método tanto en asp.net classic como en MVC, el segundo es el sugerido. Para convertir HttpRequest en HttpREquestBase simplemente envuélvalo con HttpRequestWrapper :

 public static bool GetIsJsonRequest(HttpRequest request) { return GetIsJsonRequest(new HttpRequestWrapper(request)); } 

Puedes usar

 Request.IsAjaxRequest() 

Para que puedas comprobar

 if (Request.IsAjaxRequest()) { return new JsonResult(); } return ActionResult 

Puedes usar

 Request.ContentType 

en cualquier método de controlador que esté utilizando. También puede colocar esto en un ActionFilterAttribute si lo necesita para trabajar en múltiples lugares.

Espero que esto sea mucho más eficiente.

 public static class JsonResultController { public static bool IsJsonRequest(this HttpRequestBase request) { return GetIsJsonRequest(request); } public static bool IsJsonRequest(this HttpRequest request) { return GetIsJsonRequest(request); } private static bool GetIsJsonRequest(dynamic request) { if (request == null) { throw new ArgumentNullException("request"); } bool rtn = false; const string jsonMime = "application/json"; if (request.AcceptTypes != null) { rtn = (request.AcceptTypes as string[]).Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase)); } return rtn || (request.ContentType as string ?? "").Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase)); } }