关于c#:如何在不抛出MVC控制器异常的情况下向$ .ajax报告错误?

How to report error to $.ajax without throwing exception in MVC controller?

我有一个控制器,和一个定义的方法......

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[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...

}

异常问题

  • 我们必须在设备或网络错误(如SQL连接错误)的情况下记录异常。
  • 这些消息就像用户的验证消息,我们不想记录。
  • 抛出异常也会使事件查看器泛滥。
  • 我需要一些简单的方法来报告我的$ .ajax调用的一些自定义http状态,以便它在客户端产生错误,但我不想抛出错误。

    UPDATE

    我无法更改客户端脚本,因为它与其他数据源不一致。

    到目前为止,HttpStatusCodeResult应该可以正常工作,但这是导致此问题的IIS。 无论我设置了什么错误消息,尝试了所有答案,我仍然只收到默认消息。


    这是HTTP状态代码发挥作用的地方。使用Ajax,您将能够相应地处理它们。

    1
    2
    3
    4
    5
    6
    7
    8
    [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.
    }

    这是已定义状态代码的列表。


    描述

    如何将对象返回到页面并在ajax回调中进行分析。

    样品

    1
    2
    3
    4
    5
    6
    7
    8
    [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的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $.ajax({
      url:"...",
      success: function(data){
        if (!data.success)
        {
           // do something to show the user something went wrong using data.message
        } else {
           // YES!
        }
      }
    });


    您可以在基本控制器中创建一个帮助器方法,该方法将返回服务器错误,但使用您的自定义状态代码。例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public abstract class MyBaseController : Controller
    {
        public EmptyResult ExecutionError(string message)
        {
            Response.StatusCode = 550;
            Response.Write(message);
            return new EmptyResult();
        }
    }

    您将在需要时在您的操作中调用此方法。
    在你的例子中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [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')可以在客户端全局处理,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    $(document).ready(function () {
        $.ajaxSetup({
            error: function (x, e) {
                if (x.status == 0) {
                    alert('You are offline!!
     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.
    Parsing JSON Request failed.'
    );
                } else if (e == 'timeout') {
                    alert('Request Time out.');
                } else {
                    alert('Unknow Error.
    '
    + x.responseText);
                }
            }
        });
    });


    这是我写的一个类,它将发送异常作为JSON发送回ajax请求

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    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);
                }
            }
        }

    它在应用程序的Global.asax.cs文件中注册了MVC,如下所示:

    1
    GlobalFilters.Filters.Add(new FormatExceptionAttribute());


    基于BigMike发布的内容,这就是我在NON MVC / WEBAPI webproject中所做的。

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

    它的价值(感谢BigMike!)它完美无缺。


    我发现的最佳方法如下:

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


    我将此特殊类用于Ajax错误

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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错误函数中,我测试它像:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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;
        };