recibir por obtener devolver datos con como jquery ajax internet-explorer-8 jqxhr asp.net-mvc-5.1

jquery - por - Al realizar una publicación a través de ajax, se devuelve una Solicitud incorrecta en lugar del resultado JSON



recibir datos por ajax jquery (6)

Javascript

jqXHR = $.ajax({ url: $frm.attr("action"), type: "POST", dataType: "json", cache: false, headers: headers, contentType: "application/json;charset=UTF-8", data: ko.mapping.toJSON(data, map), beforeSend: function(x) { if (x && x.overrideMimeType) { return x.overrideMimeType("application/json;charset=UTF-8"); } } }); jqXHR.fail(function(xhr, err, msg) { /* xhr.responseText NEED TO BE JSON!!! */ });

En cromo

Encabezados

Request Method:POST Status Code:400 Bad Request Request Headersview source Accept:application/json, text/javascript, */*; q=0.01 Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8,pt-BR;q=0.6,pt;q=0.4 Connection:keep-alive Content-Length:10 Content-Type:application/json;charset=UTF-8 User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36 X-Requested-With:XMLHttpRequest Request Payloadview source {Id:0} Response Headersview source Cache-Control:private Content-Length:54 Content-Type:application/json; charset=utf-8 Date:Thu, 27 Feb 2014 14:01:59 GMT Server:Microsoft-IIS/8.0 X-AspNet-Version:4.0.30319 X-AspNetMvc-Version:5.1 X-Powered-By:ASP.NET

Respuesta

[{"Nombre": "Nome", "ErrorMessage": "campo obrigatório."}]

Funciona en cromo!

En IE8

Encabezados (Solicitud)

POST /Motivos/Salvar HTTP/1.1 Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: pt-br x-requested-with: XMLHttpRequest Content-Type: application/json;charset=UTF-8 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0) Content-Length: 10 Connection: Keep-Alive Pragma: no-cache

Encabezados (Respuesta)

HTTP/1.1 400 Bad Request Cache-Control: private Content-Type: text/html Server: Microsoft-IIS/8.0 X-AspNetMvc-Version: 5.1 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Thu, 27 Feb 2014 13:51:46 GMT Content-Length: 11 Bad Request

¡¡NO TRABAJO!!

Asp.net MVC

Filtrar

public class HandleExceptionAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null) { filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; var ex = filterContext.Exception.GetBaseException(); filterContext.Result = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = new { ex.Message, ex.GetType().Name } }; filterContext.ExceptionHandled = true; } else { base.OnException(filterContext); } } }

Aplicar en GlobalFilterCollection

Controlador

[ValidateJsonAntiForgeryToken, HttpPost] public virtual JsonResult Salvar(TViewModel viewModel) { if (ModelState.IsValid) { TEntity model; if (default(TKey).Equals(viewModel.Id)) { model = Mapper.Map<TEntity>(viewModel); AdicionarEntidade(model, viewModel); } else { model = Repositorio.Get(viewModel.Id); Mapper.Map(viewModel, model, typeof(TViewModel), typeof(TEntity)); SalvarEntidade(model, viewModel); } return SalvarResult(model); } Response.StatusCode = 400; return Json(ModelState.ToJson(), JsonRequestBehavior.AllowGet); }

Extensión

public static object ToJson(this ModelStateDictionary dic, params string[] othersMessages) { var states = (from e in dic where e.Value.Errors.Count > 0 select new { Name = e.Key, e.Value.Errors[0].ErrorMessage }).ToList(); if (othersMessages != null) foreach (var message in othersMessages) states.Add(new { Name = "", ErrorMessage = message }); return states; }

Preguntas

  • ¿Por qué no tener el objeto xhr.resposeText?
  • ¿Cómo recuperar JSON de la misma manera que me recupero en Chrome?

¡Necesito el JSON para rellenar el formulario!

Notas: 03/11/2014

Cuando agrego Response.TrySkipIisCustomErrors = true; en mi control, funciona! responseText devuelve el json. ¿Por qué?


El problema que estoy viendo es que estás intentando configurar la codificación de JSON en UTF-8. Normalmente funciona bien, sin embargo, en IIS, tiene un error personalizado para informar que el UTF-8 no es necesario.

Algunas otras cosas a tener en cuenta. Estás haciendo un POST, por lo que el servidor esperará un archivo json. Si no se proporciona ninguno, no sabrá qué hacer.


He completado una prueba de falla que debería ayudar.

$.post($frm.attr("action"), ko.mapping.toJSON(data, map)) .done(function (dataVal) { //process dataVal var mystruct = GenerateCache($.parseJSON(dataVal)); }) .fail(function (jqxhr, textStatus, error) { if (jqxhr.responseText.indexOf("YourMoniker") != -1) { parseData($.parseJSON(jqxhr.responseText)); } else { var err = textStatus + '', '' + error; console.log("Request Failed: " + err); } }); function GenerateCache(data) { var obj = function () { }; obj.prototype = data; return new obj(); }

Mire específicamente el manejo de errores en la sección .fail .


IE (todas las versiones, incluido IE11) colocará "Solicitud incorrecta" en el texto de estado e ignorará el JSON que ingresó como mensaje.

Para utilizar el xhr.responseText en IE en caso de error, debe lanzar una excepción en lugar de devolver un Json o JsonResult con HttpStatusCode.BadRequest;

Entonces ... antes

Response.StatusCode = (int)HttpStatusCode.BadRequest; return Json(new { Message = "There is already a distribution set which covers part or all of this period" });

Esto funciona en Chrome, FF y cualquier navegador sano, realmente. Después:

throw new Exception("You have posted invalid datas.");

Como una excepción no controlada, se pasará al navegador como respuesta, esto funcionará en Chrome, FF e incluso en IE. No es elegante, al igual que todas las excepciones no manejadas (o solo excepciones, para el caso), pero hará el trabajo de permitirle recibir una respuesta adecuada.


No es tu controlador, está funcionando bien. Le falta un campo obligatorio: tanto IE como Chrome están devolviendo el código de estado 400 Bad Request , pero solo Chrome está procesando adecuadamente el texto de responseText y le proporciona [{"Name":"Nome","ErrorMessage":"campo obrigatório."}] lo que significa que tiene un campo de formulario faltante.

Aunque he buscado por todas partes y no he encontrado ninguna referencia a errores de IE específicos en el procesamiento de XMLHttpRequest.responseText con códigos de estado que no sean 200, parece que IE está reemplazando su cuerpo de respuesta por su propio:

Headers (Response) HTTP/1.1 400 Bad Request ... Content-Length: 11 Bad Request

Indica que el "contenido" tal como lo trata es el texto de estado de "Solicitud incorrecta", no la respuesta json adecuada (que Chrome lee como contenido de longitud 54, por ejemplo). Esto podría significar que IE está descartando su cuerpo de respuesta (lo dudo, sería increíble) o simplemente no se procesa "correctamente". Intente volcar el resto de su objeto jqXHR y los argumentos de su controlador de fail para ver si puede encontrarlo en alguna parte.


Piensa que este es un problema con IIS que intenta usar una respuesta de error personalizada en lugar de enviar el mensaje de error que el controlador está generando.

<system.webServer> ... <httpErrors existingResponse="PassThrough"></httpErrors> ... </system.webServer>

O

Response.TrySkipIisCustomErrors = true;

Referencia - https://.com/a/4029197/1304559

Echa un vistazo a esta publicación del blog http://weblog.west-wind.com/posts/2009/Apr/29/IIS-7-Error-Pages-taking-over-500-Errors

Dado que el código de respuesta se establece en 400, IIS reemplaza su contenido con su contenido de página de error personalizado


Su respuesta vuelve con Content-Type: text/html http header, pero debería ser application/json . Esto no es un problema en Chrome (y no recibes advertencias de falta de coincidencia en la consola) porque estás confiando en overrideMimeType ... lo cual, lo adivinaste, no es compatible con IE. De hecho, lo siguiente nunca se ejecuta en versiones anteriores de IE:

if (x && x.overrideMimeType) { return x.overrideMimeType("application/json;charset=UTF-8"); }

Su solución podría ser asegurarse de que el contenido se sirve con el tipo de contenido correcto. Si está familiarizado con las herramientas de manipulación como Burp Suite , puede agregar el encabezado correcto sobre la marcha y ver si eso soluciona el problema. Probablemente evitaría los métodos de AddHeader como AddHeader y vería si hay una manera de solucionarlo en un enrutamiento más alto, tal vez, a nivel.