当AJAX返回错误时,是否可以接收JsonResult对象中包含的数据?

时间:2013-06-29 03:59:56

标签: ajax asp.net-mvc json

我有这样的方法:

[HttpGet]
[Authorize]
public JsonResult SomeMethod()
    object responseJson;
    try
    {
        //All good
        responseJson = new { Data = someData };
    }
    catch (Exception ex)
    {
        //AdditionalInfo is not returned
        responseJson = new { Error = errors, AdditionalInfo = additionalInfo };
    }

    return Json(responseJson, JsonRequestBehavior.AllowGet);
}

如果方法没有返回错误,我在解析responseJson时没有问题,但是如果在Catch中创建了响应,我就无法访问AdditionalInfo。

我可以提供更多细节,但在我进入长篇第一篇文章之前,我想确保我没有遗漏一些明显的东西。

谢谢! 西蒙

1 个答案:

答案 0 :(得分:0)

如果我误解你的问题,请道歉。

有许多方法可以处理Web应用程序中的错误,但我个人发现,对于严格使用AJAX的ASP.Net MVC应用程序来说,最简单的方法是创建两种基本的异常类型。 ServerException和ClientException。基本区别在于ServerExceptions是不应该发生的错误,用户不太可能解决它们。另一方面,ClientExceptions的范围从“权限被拒绝”到“无效的电子邮件格式”。

从那里创建另一个类,它将表示应用程序将生成的所有AJAX响应的结构。例如,我使用如下内容:

public class JSONMessageObject
{
    protected IList<ClientException> _ClientExceptions = null;
    protected IList<ServerException> _ServerExceptions = null;

    public bool Success { get; set; }
    public bool LoggedIn { get; set; }
    public bool IsAdmin { get; set; }
    public object Data { get; set; }
    public IList<ClientException> ClientExceptions {
        get 
        {
            if(_ClientExceptions == null) _ClientExceptions = new List<ClientException>();
            return _ClientExceptions;
        }
        set 
        {
            _ClientExceptions = value;
        }
    }
    public IList<ServerException> ServerExceptions
    {
        get
        {
            if (_ServerExceptions == null) _ServerExceptions = new List<ServerException>();
            return _ServerExceptions;
        }
        set
        {
            _ServerExceptions = value;
        }
    }

    public string toJSON()
    {
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        return serializer.Serialize(new
        {
            Success = Success,
            LoggedIn = LoggedIn,
            IsAdmin = IsAdmin,
            Data = Data,
            ClientExceptions = from ex in ClientExceptions
                                select new
                                {
                                    Source = ex.Source,
                                    Value = ex.Value,
                                    Message = ex.Message,
                                    Number = ex.Number
                                },
            ServerExceptions = from ex in ServerExceptions
                                select new
                                {
                                    Message = ex.Message
                                }
        });
    }
}

为了让所有AJAX方法都返回此结构,您需要直接使用Json()方法。相反,我创建了一个BaseController类,所有其他控制器都继承了这个类,所以我可以使用以下调用。

private JsonResult Message(Classes.JSONMessageObject message)
{
    return Json(message, "application/json", JsonRequestBehavior.AllowGet);
}

显然,创建一些额外的重载更容易,以简化一些更常见的返回:

protected JsonResult Message()
{
    return Message(false, false, false, null);
}
protected JsonResult Message(bool success)
{
    return Message(success, false, false, null);
}
protected JsonResult Message(bool success, bool loggedIn)
{
    return Message(success, loggedIn, false, null);
}
protected JsonResult Message(bool success, bool loggedIn, bool isAdmin)
{
    return Message(success, loggedIn, isAdmin, null);
}
protected JsonResult Message(bool success, bool loggedIn, bool isAdmin, object data)
{
    return Message(new Classes.JSONMessageObject()
    {
        Success = success,
        LoggedIn = loggedIn,
        IsAdmin = isAdmin,
        Data = data
    });
}

所以这里是这种方法真正美丽的地方。由于您的方法响应都已标准化,因此您可以适当地响应任何AJAX调用,而无需知道它是什么样的调用。这意味着您不必在每个Controller方法中处理异常。只需让Global.asax Application_Error事件捕获它们:

protected void Application_Error()
{
    Exception ex = Server.GetLastError();

    if (ex is Classes.ClientException)
    {
        OutputJSON(new Classes.JSONMessageObject
        {
            ClientExceptions = { (Classes.ClientException)ex }
        });
    }
    else
    {
        WriteToDatabase(ex);
    }
}
private void WriteToDatabase(Exception ex)
{
    try
    {
        int errorRecordId;

        // Save error to the database.

        OutputJSON(new Classes.JSONMessageObject()
        {
            ServerExceptions = { new Classes.ServerException("Error saved to database. Error Id: " + errorRecordId.ToString()) }
        });
    }
    catch
    {
        // Fallback...
    }
}

完成此设置后,您可以使用JSONMessageObject类型更改AdditionalInfo以更好地满足您的需求。或者更好的是,只需将其添加到ClientException类。

希望这有帮助。