Как сообщить об ошибке в $ .ajax без исключения в контроллере MVC? - PullRequest
34 голосов
/ 02 января 2012

У меня есть контроллер и метод, как определено ...

[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...

}

Проблемы с исключениями

  1. Мы должны регистрировать исключения в случае ошибок устройства или сети, таких как ошибки подключения SQL.
  2. Эти сообщения похожи на сообщения проверки для пользователей, мы не хотим регистрироваться.
  3. Создание исключений также вызывает просмотр событий.

Мне нужен простой способ сообщить о каком-либо пользовательском статусе http моему вызову $ .ajax, чтобы он приводил к ошибке на стороне клиента, но я не хочу выдавать ошибку.

UPDATE

Я не могу изменить клиентский скрипт, потому что он становится несовместимым с другим источником данных.

Пока что HttpStatusCodeResult должен работать, но проблема заключается в IIS. Независимо от того, какое сообщение об ошибке я установил, перепробовал все ответы, но я получаю только сообщение по умолчанию.

Ответы [ 7 ]

48 голосов
/ 02 января 2012

Это где коды состояния HTTP вступают в игру.С Ajax вы сможете обрабатывать их соответствующим образом.

[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.
}

Вот список определенных кодов состояния .

9 голосов
/ 02 января 2012

Описание

Как насчет возврата объекта на вашу страницу и анализа этого в вашем ajax обратном вызове.

Sample

[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! 
    }
  }
});
4 голосов
/ 03 января 2012

Вы можете создать вспомогательный метод в базовом контроллере, который будет возвращать ошибку сервера, но с вашим пользовательским кодом состояния.Пример:

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

Вы будете вызывать этот метод в своих действиях, когда это необходимо.В вашем примере:

[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...

}

Ошибки (включая пользовательский код '550') могут обрабатываться глобально на стороне клиента следующим образом:

$(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);
            }
        }
    });
});
2 голосов
/ 02 января 2012

Это класс, который я написал, отправляет исключения обратно в запросы ajax как JSON

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);
            }
        }
    }

Он регистрируется в MVC в файле Global.asax.cs вашего приложения, например:

GlobalFilters.Filters.Add(new FormatExceptionAttribute());
1 голос
/ 05 мая 2015

Исходя из того, что опубликовал BigMike, это было то, что я сделал в своем веб-проекте NON MVC / WEBAPI.

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

Для чего он стоит (и спасибо BigMike!) Он работал отлично.

1 голос
/ 29 мая 2013

Лучший способ, который я нашел, выглядит следующим образом:

// Return error status and custom message as 'errorThrown' parameter of ajax request
return new HttpStatusCodeResult(400, "Ajax error test");
1 голос
/ 02 января 2012

Я использую этот особый класс для ошибок Ajax

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);
    }
}

Код состояния - это пользовательский код состояния HTTP, и в глобальной функции ошибок Ajax я проверяю его следующим образом:

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;
    };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...