我可以从JsonResult返回自定义错误到jQuery ajax错误方法吗?

时间:2012-02-15 17:45:59

标签: ajax asp.net-mvc-3 jquery

如何将自定义错误信息从ASP.NET MVC3 JsonResult方法传递到error(或successcomplete,如果需要){{ {1}}?理想情况下,我希望能够:

  • 仍然在服务器上抛出错误(这用于记录)
  • 检索有关客户端错误的自定义信息

以下是我的代码的基本版本:

控制器JsonResult方法

jQuery.ajax()

的JavaScript

public JsonResult DoStuff(string argString)
{
    string errorInfo = "";

    try
    {
        DoOtherStuff(argString);
    }
    catch(Exception e)
    {
        errorInfo = "Failed to call DoOtherStuff()";
        //Edit HTTP Response here to include 'errorInfo' ?
        throw e;
    }

    return Json(true);
}

我尝试过的事情(没有成功):

  • $.ajax({ type: "POST", url: "../MyController/DoStuff", data: {argString: "arg string"}, dataType: "json", traditional: true, success: function(data, statusCode, xhr){ if (data === true) //Success handling else //Error handling here? But error still needs to be thrown on server... }, error: function(xhr, errorType, exception) { //Here 'exception' is 'Internal Server Error' //Haven't had luck editing the Response on the server to pass something here } }); 块返回错误信息
    • 这样可行,但不能抛出异常
  • catch块中编辑HTTP响应
    • 然后在jQuery错误处理程序
    • 中检查catch
    • xhr等包含默认的ASP.NET错误页面,但不包含我的信息
    • 我认为这可能是可能的,但我做错了?

5 个答案:

答案 0 :(得分:50)

您可以编写自定义错误过滤器:

public class JsonExceptionFilterAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.HttpContext.Response.StatusCode = 500;
            filterContext.ExceptionHandled = true;
            filterContext.Result = new JsonResult
            {
                Data = new
                {
                    // obviously here you could include whatever information you want about the exception
                    // for example if you have some custom exceptions you could test
                    // the type of the actual exception and extract additional data
                    // For the sake of simplicity let's suppose that we want to
                    // send only the exception message to the client
                    errorMessage = filterContext.Exception.Message
                },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
    }
}

然后将其注册为全局过滤器或仅应用于您要使用AJAX调用的特定控制器/操作。

在客户端:

$.ajax({
    type: "POST",
    url: "@Url.Action("DoStuff", "My")",
    data: { argString: "arg string" },
    dataType: "json",
    traditional: true,
    success: function(data) {
        //Success handling
    },
    error: function(xhr) {
        try {
            // a try/catch is recommended as the error handler
            // could occur in many events and there might not be
            // a JSON response from the server
            var json = $.parseJSON(xhr.responseText);
            alert(json.errorMessage);
        } catch(e) { 
            alert('something bad happened');
        }
    }
});

显然,您可能很快就会为每个AJAX请求编写重复的错误处理代码,因此最好为页面上的所有AJAX请求编写一次:

$(document).ajaxError(function (evt, xhr) {
    try {
        var json = $.parseJSON(xhr.responseText);
        alert(json.errorMessage);
    } catch (e) { 
        alert('something bad happened');
    }
});

然后:

$.ajax({
    type: "POST",
    url: "@Url.Action("DoStuff", "My")",
    data: { argString: "arg string" },
    dataType: "json",
    traditional: true,
    success: function(data) {
        //Success handling
    }
});

另一种可能性是调整a global exception handler I presented,以便在ErrorController中检查它是否是一个AJAX请求,并简单地将异常详细信息作为JSON返回。

答案 1 :(得分:10)

上述建议不适用于远程客户端的IIS。他们将收到一个标准的错误页面,如500.htm,而不是带有消息的响应。 您必须在web.config中使用customError模式,或添加

<system.webServer>
        <httpErrors existingResponse="PassThrough" />
    </system.webServer>

  

“你也可以进入IIS管理器 - &gt;错误页面然后点击   右键单击“编辑功能设置...”并将选项设置为“详细   错误“那么它将是你的应用程序处理错误和   不是IIS。“

答案 2 :(得分:4)

您可以返回JsonResult并显示错误并在javascript端跟踪状态以显示错误消息:

 JsonResult jsonOutput = null;
        try
        {
           // do Stuff
        }
        catch
        {
            jsonOutput = Json(
                 new
                 {
                     reply = new
                     {
                         status = "Failed",
                         message = "Custom message "
                     }
                 });
        }
        return jsonOutput ;

答案 3 :(得分:0)

我的MVC项目没有返回任何错误消息(自定义或其他)。 我发现这对我很有用:

$.ajax({
        url: '/SomePath/Create',
        data: JSON.stringify(salesmain),
        type: 'POST',
        contentType: 'application/json;',
        dataType: 'json',
        success: function (result) {

            alert("start JSON");
            if (result.Success == "1") {
                window.location.href = "/SomePath/index";
            }
            else {
                alert(result.ex);
            }

            alert("end JSON");
        },
        error: function (xhr) {

            alert(xhr.responseText);

        }
        //error: AjaxFailed
    });

显示xhr.responseText会产生非常详细的HTML格式警报消息。

答案 4 :(得分:0)

如果由于某种原因您无法发送服务器错误。您可以执行以下操作。

服务器端

 var items = Newtonsoft.Json.JsonConvert.DeserializeObject<SubCat>(data); // Returning a parse object or complete object

        if (!String.IsNullOrEmpty(items.OldName))
        {
            DataTable update = Access.update_SubCategories_ByBrand_andCategory_andLikeSubCategories_BY_PRODUCTNAME(items.OldName, items.Name, items.Description);

            if(update.Rows.Count > 0)
            {
                List<errors> errors_ = new List<errors>();
                errors_.Add(new errors(update.Rows[0]["ErrorMessage"].ToString(), "Duplicate Field", true));

                return Newtonsoft.Json.JsonConvert.SerializeObject(errors_[0]); // returning a stringify object which equals a string | noncomplete object
            }

        }

        return items;

客户端

 $.ajax({
            method: 'POST',
            url: `legacy.aspx/${place}`,
            contentType: 'application/json',
            data:  JSON.stringify({data_}),              
            headers: {
                'Accept': 'application/json, text/plain, *',
                'Content-type': 'application/json',
                'dataType': 'json'
            },
            success: function (data) {

                if (typeof data.d === 'object') { //If data returns an object then its a success

                    const Toast = Swal.mixin({
                        toast: true,
                        position: 'top-end',
                        showConfirmButton: false,
                        timer: 3000
                    })

                    Toast.fire({
                        type: 'success',
                        title: 'Information Saved Successfully'
                    })

                    editChange(place, data.d, data_);

                } else { // If data returns a stringify object or string then it failed and run error

                    var myData = JSON.parse(data.d);

                    Swal.fire({
                      type: 'error',
                      title: 'Oops...',
                      text: 'Something went wrong!',
                      footer: `<a href='javascript:showError("${myData.errorMessage}", "${myData.type}", ${data_})'>Why do I have this issue?</a>`
                    })
                }
            },
            error: function (error) { console.log("FAIL....================="); }
        });