web-dev-qa-db-de.com

Wie kann ich einen Fehler an $ .ajax melden, ohne eine Ausnahme in der MVC-Steuerung auszulösen?

Ich habe einen Controller und eine Methode wie definiert ...

[HttpPost]
public ActionResult UpdateUser(UserInformation model){

   // Instead of throwing exception
   throw new InvalidOperationException("Something went wrong");


   // I need something like 
   return ExecutionError("Error Message");

   // which should be received as an error to my 
   // $.ajax at client side...

}

Probleme mit Ausnahmen

  1. Wir müssen Ausnahmen für Geräte- oder Netzwerkfehler wie SQL Connectivity-Fehler protokollieren. 
  2. Diese Nachrichten sind wie Bestätigungsmeldungen für Benutzer, wir möchten nicht protokollieren.
  3. Ausnahmen werfen auch die Ereignisanzeige.

Ich brauche eine einfache Möglichkeit, meinem $ .ajax-Aufruf einen benutzerdefinierten http-Status zu melden, sodass auf Client-Seite ein Fehler angezeigt wird, ich möchte jedoch keinen Fehler auslösen.

UPDATE

Ich kann das Clientskript nicht ändern, da es mit anderen Datenquellen inkonsistent wird. 

Bisher sollte HttpStatusCodeResult funktionieren, aber IIS verursacht das Problem hier. Unabhängig von der Fehlermeldung, die ich eingestellt habe, habe ich alle Antworten ausprobiert, ich erhalte jedoch nur die Standardnachricht. 

32
Akash Kava

Hier kommen HTTP-Statuscodes ins Spiel. Mit Ajax können Sie entsprechend damit umgehen.

[HttpPost]
public ActionResult UpdateUser(UserInformation model){
    if (!UserIsAuthorized())
        return new HttpStatusCodeResult(401, "Custom Error Message 1"); // Unauthorized
    if (!model.IsValid)
        return new HttpStatusCodeResult(400, "Custom Error Message 2"); // Bad Request
    // etc.
}

Hier ist eine Liste der definierten Statuscodes .

46
Dennis Traub

Beschreibung

Wie wäre es, wenn Sie ein Objekt auf Ihre Seite zurückbringen und dies in Ihrem ajax Callback analysieren.

Probe

[HttpPost]
public ActionResult UpdateUser(UserInformation model)
{
    if (SomethingWentWrong)
        return this.Json(new { success = false, message = "Uuups, something went wrong!" });

    return this.Json(new { success=true, message=string.Empty});
}

jQuery

$.ajax({
  url: "...",
  success: function(data){
    if (!data.success) 
    {
       // do something to show the user something went wrong using data.message
    } else {
       // YES! 
    }
  }
});
9
dknaack

Sie können eine Hilfsmethode in einem Basiscontroller erstellen, die einen Serverfehler mit Ihrem benutzerdefinierten Statuscode zurückgibt. Beispiel:

public abstract class MyBaseController : Controller
{
    public EmptyResult ExecutionError(string message)
    {
        Response.StatusCode = 550;
        Response.Write(message);
        return new EmptyResult();
    }
}

Sie rufen diese Methode bei Bedarf in Ihren Aktionen auf. In Ihrem Beispiel:

[HttpPost]
public ActionResult UpdateUser(UserInformation model){

   // Instead of throwing exception
   // throw new InvalidOperationException("Something went wrong");


   // The thing you need is 
   return ExecutionError("Error Message");

   // which should be received as an error to my 
   // $.ajax at client side...

}

Die Fehler (einschließlich des benutzerdefinierten Codes '550') können auf der Clientseite global wie folgt behandelt werden:

$(document).ready(function () {
    $.ajaxSetup({
        error: function (x, e) {
            if (x.status == 0) {
                alert('You are offline!!\n Please Check Your Network.');
            } else if (x.status == 404) {
                alert('Requested URL not found.');
/*------>*/ } else if (x.status == 550) { // <----- THIS IS MY CUSTOM ERROR CODE
                alert(x.responseText);
            } else if (x.status == 500) {
                alert('Internel Server Error.');
            } else if (e == 'parsererror') {
                alert('Error.\nParsing JSON Request failed.');
            } else if (e == 'timeout') {
                alert('Request Time out.');
            } else {
                alert('Unknow Error.\n' + x.responseText);
            }
        }
    });
});
4
shizik

Dies ist eine Klasse, die ich als JSON geschrieben habe

public class FormatExceptionAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult()
                                        {
                                            ContentType = "application/json",
                                            Data = new
                                                    {
                                                        name = filterContext.Exception.GetType().Name,
                                                        message = filterContext.Exception.Message,
                                                        callstack = filterContext.Exception.StackTrace
                                                    },
                                            JsonRequestBehavior = JsonRequestBehavior.AllowGet
                                        };

                filterContext.ExceptionHandled = true;
                filterContext.HttpContext.Response.StatusCode = 500;
                filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; 
            }
            else
            {
                base.OnException(filterContext);
            }
        }
    }

Es wird bei MVC in der Datei Global.asax.cs Ihrer Anwendung wie folgt registriert:

GlobalFilters.Filters.Add(new FormatExceptionAttribute());
2
Jason

Der beste Weg, den ich gefunden habe, ist wie folgt:

// Return error status and custom message as 'errorThrown' parameter of ajax request
return new HttpStatusCodeResult(400, "Ajax error test");
1
GP24

Basierend auf dem, was BigMike gepostet hat, habe ich dies in meinem NON MVC/WEB API-Webprojekt getan.

Response.ContentType = "application/json";
Response.StatusCode = 400;
Response.Write (ex.Message);

Für was es wert ist (und danke BigMike!) Es hat perfekt funktioniert.

1
roblem

Ich benutze diese besondere Klasse für Ajax-Fehler

public class HttpStatusCodeResultWithJson : JsonResult
{
    private int _statusCode;
    private string _description;
    public HttpStatusCodeResultWithJson(int statusCode, string description = null)
    {
        _statusCode = statusCode;
        _description = description;
    }
    public override void ExecuteResult(ControllerContext context)
    {
        var httpContext = context.HttpContext;
        var response = httpContext.Response;
        response.StatusCode = _statusCode;
        response.StatusDescription = _description;
        base.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        base.ExecuteResult(context);
    }
}

Statuscode ist ein benutzerdefinierter HTTP-Statuscode und in einer globalen Ajax-Fehlerfunktion teste ich ihn wie folgt:

MyNsp.ErrorAjax = function (xhr, st, str) {
        if (xhr.status == '418') {
            MyNsp.UI.Message("Warning: session expired!");
            return;
        }
        if (xhr.status == "419") {
            MyNsp.UI.Message("Security Token Missing");
            return;
        }
        var msg = 'Error: ' + (str ? str : xhr.statusText);
        MyNsp.UI.Message('Error. - status:' + st + "(" + msg + ")");
        return;
    };
1
BigMike