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
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.
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 .
Wie wäre es, wenn Sie ein Objekt auf Ihre Seite zurückbringen und dies in Ihrem ajax
Callback analysieren.
[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!
}
}
});
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);
}
}
});
});
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());
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");
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.
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;
};