2016-08-02 12 views
3

jQuery 1.11.3 Post empfängt ungültige Anforderung von HttpResponseMessage, geht jedoch nicht in fehl. Nachricht vom Server ist die folgende Zeichenfolge:jQuery 1.11.3 Post empfängt ungültige Anforderung, geht aber nicht in Fehler

"Statuscode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Inhalt: , Header: {}"

Sollte ich nicht bekommen Objekt zurück von HttpResponseMessage, die Bad Request sagt? Ich verwende IIS Express.

Bad request

Zurück Ende:

[HttpPost] 
public HttpResponseMessage DeleteOrderRow(int orderRowId) 
{ 
    var row = OrderRowData.LoadItem(orderRowId); 
    if (row == null) 
    { 
     AddAlert(AlertStyles.Danger, "Order row does not exist"); 
     //Below is the example being returned 
     return new HttpResponseMessage(HttpStatusCode.BadRequest); 
    } 
    OrderRowData.Delete(orderRowId); 
    AddAlert(AlertStyles.Success, "Order row has been removed"); 
    return new HttpResponseMessage(HttpStatusCode.OK); 
} 

jQuery:

$(document).on('click', '.delete-order-row', function (event) { 
    event.preventDefault(); 

    var element = $(this); 
    var id = element.data('id'); 

    if (id == null || id === -1) { 
     element.closest('tr').remove(); 
    } else { 
     var url = element.attr('href'); 
     $.post(url, { orderRowId: id }) 
      .done(function (data) { 
       element.closest('tr').remove(); 
      }) 
      .fail(function (xhr, status, error) { 
       location.reload(); 
      }); 
    } 
}); 

Update: Checked Netzwerkverbindung nach Spitze von @smoksnes. Der Server sendet tatsächlich 200 OK, obwohl return new HttpResponseMessage(HttpStatusCode.BadRequest); vom Back-End gesendet wird. Ist das normales Verhalten von IIS Express?

Network tab

Update 2: es Client-Seite mit diesem Code wird gelöst. Basierend auf @smoksnes Antwort und dass IExceptionFilter und ExceptionFilterAttribute ist nicht in meinem Projekt Ich vermute, Umbraco. Hat jemand anderes dies in Umbraco erlebt?

.done(function (data) { 
    if (data.indexOf("StatusCode: 400") !== -1) { 
     $(window).scrollTop(0); 
     location.reload(); 
    } else { 
     element.closest('tr').remove(); 
    } 
}) 
+1

Überprüfen Sie, dass der Server tatsächlich 400 als den Statuscode in der Registerkarte Netzwerk zurückgibt. Ich habe einige Implementierungen gesehen, die eine 200 zurückgeben, aber mit einem JSON, der einen anderen Statuscode enthält. – smoksnes

+0

Ich habe nicht darüber nachgedacht und Sie sind, der Server gab 200 OK zurück. Weißt du, ob dies normales Verhalten von IIS Express ist? 'neue HttpResponseMessage (HttpStatusCode.BadRequest);' sollte eindeutig 400 imao sein. – Ogglas

Antwort

0

es Client-Seite mit diesem Code wurde gelöst. Basierend auf @smoksnes Antwort und dass IExceptionFilter und ExceptionFilterAttribute ist nicht in meinem Projekt Ich vermute, Umbraco.

.done(function (data) { 
    if (data.indexOf("StatusCode: 400") !== -1) { 
     $(window).scrollTop(0); 
     location.reload(); 
    } else { 
     element.closest('tr').remove(); 
    } 
}) 
1

Ist das ein normales Verhalten von IIS Express?

In einem leeren Projekt sollte 400 Bad Request zurückgegeben werden.

400 Bad Request

public HttpResponseMessage DeleteOrderRow() 
{ 
    return new HttpResponseMessage(HttpStatusCode.BadRequest); 
} 

Aber wie ich in den Kommentaren erwähnt scheinen Sie eine 200 OK zu bekommen, auf der Grundlage der Informationen in der Registerkarte Netzwerk. Dies führt dazu, dass das Clientskript done() eingibt. Dies kann durch benutzerdefinierte Filter verursacht werden.

Suchen Sie in Ihrem Projekt nach IExceptionFilter und ExceptionFilterAttribute.

Eine gemeinsame Lösung ist das Hinzufügen dieser Filter in Gobal.asax:

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 


public class FilterConfig 
{ 
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); // Or whatever filter you got. 
     filters.Add(new AjaxExceptionLoggingFilter()); 
    } 
} 

Sie die Antwort in eine 200 OK ändern können.

Auch, basierend auf der URL scheinen Sie Umbraco zu verwenden. Ich bin nicht sehr damit vertraut, aber da könnte etwas Magie vor sich gehen. Wenn Sie es nicht auf Server-Seite lösen können, können Sie es auf Client-Seite lösen:

//Quick fix (dirty) 
    $.post(url, { orderRowId: id }) 
     .done(function (data) { 
      if(data.StatusCode != 200) 
      { 
       // do error stuff.. 
       return; 
      } 
      element.closest('tr').remove(); 
     }) 
     .fail(function (xhr, status, error) { 
      location.reload(); 
     }); 

Oder mit ajaxPrefilter.

// Written by hand and not tested. 
$.ajaxPrefilter(function(options, originalOptions, jqXHR) { 
    var success = options.success; 
    options.success = function(data, textStatus, jqXHR) { 
     // override success handling 
     if(data && data.StatusCode != 200) 
     { 
      // Go to error. 
      return options.error(data); 
     } 
     else if(typeof(success) === "function") return success(data, textStatus, jqXHR); 
    }; 
    var error = options.error; 
    options.error = function(jqXHR, textStatus, errorThrown) { 
     // override error handling 
     if(typeof(error) === "function") return error(jqXHR, textStatus, errorThrown); 
    }; 
}); 

Oder mit latenten:

$.ajaxPrefilter(function(opts, originalOpts, jqXHR) { 
    // you could pass this option in on a "retry" so that it doesn't 
    // get all recursive on you. 
    if (opts.retryAttempt) { 
     return; 
    } 

    var dfd = $.Deferred(); 

    // if the request works, return normally 
    jqXHR.done(function(result){ 
     // Maybe check for result != null? 
     if(result.StatusCode != 200) { 
      dfd.reject() // Manually reject 
     } 
     else { 
      dfd.resolve(result); 
     } 

    }); 

    jqXHR.fail(dfd.reject); 

    // NOW override the jqXHR's promise functions with our deferred 
    return dfd.promise(jqXHR); 
}); 

Ein vollständigeres Beispiel mit ajaxPrefilter kann here finden.

+0

Danke für eine klare Antwort. Ich kann 'IExceptionFilter' oder' ExceptionFilterAttribute' nicht im Projekt finden. Ich benutze jedoch Umbraco, was das Problem sein könnte. – Ogglas

+0

Ich habe meine Antwort mit einer möglichen Problemumgehung bearbeitet. – smoksnes

+1

Dank @smoksnes, bereits eine Client-Seite behoben. Leider ist die Antwort nicht einmal ein Objekt, daher muss ich eine Zeichenfolge nach "StatusCode: 400" überprüfen. Sie können sehen, wie ich es in meiner Frage gemacht habe. – Ogglas

0

Ich denke, dass das Problem ist, dass Sie Zurückgeben eines HttpResponseMessage jedes Mal sind, sollten Sie eine Antwort Ausnahme werfen statt:

var resp = new HttpResponseMessage(HttpStatusCode.BadRequest); 
throw new HttpResponseException(resp); 
+0

Dies funktioniert nicht 100%, es geht in fehl, aber es ist, weil der Server mit einer HTTP 500 Internal Server Fehlermeldung reagiert. – Ogglas

+0

versuchen Sie, indem Sie den Rückgabetyp von Ihrer DeleteOrderRow-Funktion zu IHttpActionResult ändern und dann BadRequest zurückgeben ("Bestellzeile existiert nicht"); (oder für den Erfolg Ok()); – Eyescream