ASP.NET MVC Ajax-Fehlerbehandlung

Lesezeit: 6 Minuten

Wie gehe ich mit Ausnahmen um, die in einem Controller ausgelöst werden, wenn jquery ajax eine Aktion aufruft?

Zum Beispiel möchte ich einen globalen Javascript-Code, der während eines Ajax-Aufrufs bei jeder Art von Serverausnahme ausgeführt wird, der die Ausnahmemeldung im Debug-Modus oder nur eine normale Fehlermeldung anzeigt.

Auf der Clientseite rufe ich eine Funktion für den Ajax-Fehler auf.

Muss ich auf der Serverseite einen benutzerdefinierten Aktionsfilter schreiben?

  • Sehen Beckmanns Beitrag für ein gutes Beispiel. Darins Antwort auf diesen Beitrag ist gut, aber setzen Sie nicht den richtigen Statuscode für einen Fehler.

    – Dan

    11. Oktober 11 um 9:50 Uhr

  • Leider ist diese Verbindung jetzt unterbrochen

    – Chris Neville

    7. Oktober 14 um 10:09 Uhr

  • Hier ist der Link zur Wayback-Maschine: web.archive.org/web/20111011105139/http://beckelman.net/post/…

    – BruceHill

    27. Juni 16 um 12:14 Uhr

ASPNET MVC Ajax Fehlerbehandlung
Darin Dimitrow

Wenn der Server einen anderen Statuscode als 200 sendet, wird der Fehlerrückruf ausgeführt:

$.ajax({
    url: '/foo',
    success: function(result) {
        alert('yeap');
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('oops, something bad happened');
    }
});

und um einen globalen Fehlerbehandler zu registrieren, könnten Sie die verwenden $.ajaxSetup() Methode:

$.ajaxSetup({
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('oops, something bad happened');
    }
});

Eine andere Möglichkeit ist die Verwendung von JSON. Sie könnten also einen benutzerdefinierten Aktionsfilter auf dem Server schreiben, der Ausnahmen abfängt und sie in eine JSON-Antwort umwandelt:

public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;
        filterContext.Result = new JsonResult
        {
            Data = new { success = false, error = filterContext.Exception.ToString() },
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };
    }
}

und schmücken Sie dann Ihre Controller-Aktion mit diesem Attribut:

[MyErrorHandler]
public ActionResult Foo(string id)
{
    if (string.IsNullOrEmpty(id))
    {
        throw new Exception("oh no");
    }
    return Json(new { success = true });
}

und schließlich aufrufen:

$.getJSON('/home/foo', { id: null }, function (result) {
    if (!result.success) {
        alert(result.error);
    } else {
        // handle the success
    }
});

  • Danke dafür, Letzteres war das, wonach ich gesucht habe. Gibt es also für die asp.net mvc-Ausnahme eine bestimmte Möglichkeit, sie auszulösen, damit sie vom jquery-Fehlerbehandler abgefangen werden kann?

    – Shawn Mclean

    16. Januar 11 um 20:16 Uhr

  • @Lol Coder, egal wie Sie eine Ausnahme innerhalb der Controller-Aktion auslösen, der Server gibt 500 Statuscode und die zurück error Rückruf wird ausgeführt.

    – Darin Dimitrow

    16. Januar 11 um 20:22 Uhr

  • Danke, perfekt, genau das was ich gesucht habe.

    – Shawn Mclean

    16. Januar 11 um 20:26 Uhr

  • Wäre ein Statuscode von 500 nicht irgendwie falsch? Um dieses Kap broadcast.oreilly.com/2011/06/… : “Nicht erkennen, dass ein 4xx-Fehler bedeutet, dass ich es vermasselt habe und ein 5xx bedeutet, dass Sie es vermasselt haben” – wobei ich der Client und Sie der Server sind.

    – Chris Neville

    7. Oktober 14 um 10:07 Uhr


  • Diese Antwort gilt noch für die neueren Versionen von ASPNET?

    – guck

    29. Mai ’15 um 17:36 Uhr

Nachdem ich gegoogelt habe, schreibe ich eine einfache Ausnahmebehandlung basierend auf dem MVC-Aktionsfilter:

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;
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    filterContext.Exception.Message,
                    filterContext.Exception.StackTrace
                }
            };
            filterContext.ExceptionHandled = true;
        }
        else
        {
            base.OnException(filterContext);
        }
    }
}

und schreibe in global.ascx:

 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 {
      filters.Add(new HandleExceptionAttribute());
 }

und schreiben Sie dann dieses Skript auf das Layout oder die Musterseite:

<script type="text/javascript">
      $(document).ajaxError(function (e, jqxhr, settings, exception) {
                       e.stopPropagation();
                       if (jqxhr != null)
                           alert(jqxhr.responseText);
                     });
</script>

Schließlich sollten Sie den benutzerdefinierten Fehler aktivieren. und dann genieße es 🙂

  • Ich kann den Fehler in Firebug sehen, aber er leitet nicht zur Fehlerseite weiter.?

    – Benutzer2067567

    26. April 13 um 14:20 Uhr

  • Danke dafür! sollte als Antwort IMO markiert werden, da es auf Ajax-Anforderungen filtert und die richtige Klasse erbt, anstatt das, was das HandleErrorAttribute erbt

    – mtbennett

    29. April 13 um 5:22 Uhr

  • Ich denke, dass “Request.IsAjaxRequest()” manchmal nicht so zuverlässig ist.

    – Will Huang

    6. April 16 um 6:35 Uhr

  • Für die Debug-Konfiguration funktioniert es immer, aber nicht immer in der Release-Konfiguration und gibt stattdessen HTML zurück. Hat jemand eine Problemumgehung für diesen Fall?

    – Hitendra

    27. September 16 um 13:40 Uhr

Leider ist keine der Antworten gut für mich. Überraschenderweise ist die Lösung viel einfacher. Rückgabe vom Controller:

return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);

Und handhaben Sie es als Standard-HTTP-Fehler auf dem Client, wie Sie möchten.

  • @Will Huang: der Name der Ausnahmeinstanz

    – schmendrick

    17. Oktober 16 um 15:22 Uhr

  • Ich muss das erste Argument zu werfen int. Auch wenn ich dies tue, wird das Ergebnis an die übergeben ajax success Handler, und nicht die error Handler. Ist dies das erwartete Verhalten?

    – Jonathan Holz

    23. Juni 17 um 23:35 Uhr

Ich habe eine schnelle Lösung, weil ich wenig Zeit hatte und es funktionierte ok. Obwohl ich denke, dass die Verwendung eines Ausnahmefilters die bessere Option ist, kann meine Lösung vielleicht helfen, falls eine einfache Lösung benötigt wird.

Ich habe folgendes gemacht. In der Controller-Methode habe ich ein JsonResult mit einer Eigenschaft „Success“ in den Daten zurückgegeben:

    [HttpPut]
    public JsonResult UpdateEmployeeConfig(EmployeConfig employeToSave) 
    {
        if (!ModelState.IsValid)
        {
            return new JsonResult
            {
                Data = new { ErrorMessage = "Model is not valid", Success = false },
                ContentEncoding = System.Text.Encoding.UTF8,
                JsonRequestBehavior = JsonRequestBehavior.DenyGet
            };
        }
        try
        {
            MyDbContext db = new MyDbContext();

            db.Entry(employeToSave).State = EntityState.Modified;
            db.SaveChanges();

            DTO.EmployeConfig user = (DTO.EmployeConfig)Session["EmployeLoggin"];

            if (employeToSave.Id == user.Id)
            {
                user.Company = employeToSave.Company;
                user.Language = employeToSave.Language;
                user.Money = employeToSave.Money;
                user.CostCenter = employeToSave.CostCenter;

                Session["EmployeLoggin"] = user;
            }
        }
        catch (Exception ex) 
        {
            return new JsonResult
            {
                Data = new { ErrorMessage = ex.Message, Success = false },
                ContentEncoding = System.Text.Encoding.UTF8,
                JsonRequestBehavior = JsonRequestBehavior.DenyGet
            };
        }

        return new JsonResult() { Data = new { Success = true }, };
    }

Später im Ajax-Aufruf habe ich nur nach dieser Eigenschaft gefragt, ob ich eine Ausnahme hatte:

$.ajax({
    url: 'UpdateEmployeeConfig',
    type: 'PUT',
    data: JSON.stringify(EmployeConfig),
    contentType: "application/json;charset=utf-8",
    success: function (data) {
        if (data.Success) {
            //This is for the example. Please do something prettier for the user, :)
            alert('All was really ok');                                           
        }
        else {
            alert('Oups.. we had errors: ' + data.ErrorMessage);
        }
    },
    error: function (request, status, error) {
       alert('oh, errors here. The call to the server is not working.')
    }
});

Hoffe das hilft. Fröhlicher Code! 😛

In Übereinstimmung mit alehos Antwort hier ein vollständiges Beispiel. Es funktioniert wie ein Zauber und ist super einfach.

Controller-Code

[HttpGet]
public async Task<ActionResult> ChildItems()
{
    var client = TranslationDataHttpClient.GetClient();
    HttpResponseMessage response = await client.GetAsync("childItems);

    if (response.IsSuccessStatusCode)
        {
            string content = response.Content.ReadAsStringAsync().Result;
            List<WorkflowItem> parameters = JsonConvert.DeserializeObject<List<WorkflowItem>>(content);
            return Json(content, JsonRequestBehavior.AllowGet);
        }
        else
        {
            return new HttpStatusCodeResult(response.StatusCode, response.ReasonPhrase);
        }
    }
}

Javascript-Code in der Ansicht

var url="@Html.Raw(@Url.Action("ChildItems", "WorkflowItemModal")";

$.ajax({
    type: "GET",
    dataType: "json",
    url: url,
    contentType: "application/json; charset=utf-8",
    success: function (data) {
        // Do something with the returned data
    },
    error: function (xhr, status, error) {
        // Handle the error.
    }
});

Hoffe, das hilft jemand anderem!

1644072125 682 ASPNET MVC Ajax Fehlerbehandlung
Brian Kugel

Zur Behandlung von Fehlern bei Ajax-Aufrufen auf der Client-Seite weisen Sie dem eine Funktion zu error Option des Ajax-Aufrufs.

Um eine Voreinstellung global zu setzen, können Sie die hier beschriebene Funktion verwenden:
http://api.jquery.com/jQuery.ajaxSetup.

.

784350cookie-checkASP.NET MVC Ajax-Fehlerbehandlung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy