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



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

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

这是我的代码的基本版本:

控制器JsonResult方法

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

JavaScript

$.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块返回错误信息
    • 这是有效的,但不能抛出异常
  • 编辑catch块中的HTTP响应
    • 然后在jQuery错误处理程序中检查xhr
    • xhr.getResponseHeader()等包含默认的ASP.NET错误页,但没有我的任何信息
    • 我想这可能是可能的,但我只是做错了

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

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

另一种可能性是调整我提供的全局异常处理程序,以便在ErrorController中检查它是否是AJAX请求,并简单地将异常详细信息作为JSON返回。

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

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

"您也可以进入IIS管理器-->错误页面,然后单击右键单击"编辑功能设置…"并将选项设置为"详细errors",则将由您的应用程序处理该错误而不是IIS。"

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

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

我的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格式的警报消息。

如果由于某种原因无法发送服务器错误。这里有一个你可以做的选项。

服务器端

 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....================="); }
        });

相关内容

最新更新