Asp.net mvc 如何从HandleError筛选器返回JSON?

Asp.net mvc 如何从HandleError筛选器返回JSON?,asp.net-mvc,Asp.net Mvc,aspnet mvc具有HandleError筛选器,如果发生错误,该筛选器将返回视图,但是如果调用JsonResult操作时发生错误,如何返回表示错误的JSON对象 我不想将代码包装在每个操作方法中,这些方法在try/catch中返回一个JsonResult来完成它,我更愿意通过添加一个“HandleJsonError”属性或将现有的HandleError属性用于所需的操作方法。也许您可以创建自己的属性,并拥有一个接受View或Json枚举值的构造函数值。下面是我使用的自定义授权属性来演示我的

aspnet mvc具有HandleError筛选器,如果发生错误,该筛选器将返回视图,但是如果调用JsonResult操作时发生错误,如何返回表示错误的JSON对象


我不想将代码包装在每个操作方法中,这些方法在try/catch中返回一个JsonResult来完成它,我更愿意通过添加一个“HandleJsonError”属性或将现有的HandleError属性用于所需的操作方法。

也许您可以创建自己的属性,并拥有一个接受View或Json枚举值的构造函数值。下面是我使用的自定义授权属性来演示我的意思。这样,当json请求的身份验证失败时,它会以json错误响应,如果返回视图,则返回json错误

   public enum ActionResultTypes
   {
       View,
       Json
   }

    public sealed class AuthorizationRequiredAttribute : ActionFilterAttribute, IAuthorizationFilter
    {
        public ActionResultTypes ActionResultType { get; set; }

        public AuthorizationRequiredAttribute(ActionResultTypes actionResultType)
        {
            this.ActionResultType = ActionResultType;
        }
    }

    //And used like
    [AuthorizationRequired(ActionResultTypes.View)]
    public ActionResult About()
    {
    }

看看HandleErrorAttribute的MVC实现。它返回一个ViewResult。您可以编写自己的版本(HandleJsonErrorAttribute),返回JsonResult。

简而言之,方法是扩展HandleErrorAttribute,如下所示:

public class OncHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        // Elmah-Log only handled exceptions
        if (context.ExceptionHandled)
            ErrorSignal.FromCurrentContext().Raise(context.Exception);

        if (context.HttpContext.Request.IsAjaxRequest())
        {
            // if request was an Ajax request, respond with json with Error field
            var jsonResult = new ErrorController { ControllerContext = context }.GetJsonError(context.Exception);
            jsonResult.ExecuteResult(context);
            context.ExceptionHandled = true;
        }
        else
        {
            // if not an ajax request, continue with logic implemented by MVC -> html error page
            base.OnException(context);
        }
    }
}
如果不需要,请删除Elmah日志代码行。我使用一个控制器根据错误和上下文返回json。以下是示例:

    public class ErrorController : Controller
{
    public ActionResult GetJsonError(Exception ex)
    {
        var ticketId = Guid.NewGuid(); // Lets issue a ticket to show the user and have in the log

        Request.ServerVariables["TTicketID"] = ticketId.ToString(); // Elmah will show this in a nice table

        ErrorSignal.FromCurrentContext().Raise(ex); //ELMAH Signaling

        ex.Data.Add("TTicketID", ticketId.ToString()); // Trying to see where this one gets in Elmah

        return Json(new { Error = String.Format("Support ticket: {0}\r\n Error: {1}", ticketId, ex.ToString()) }, JsonRequestBehavior.AllowGet);
    }
我在上面添加了一些票证信息,你可以忽略这个。根据过滤器的实现方式(扩展默认的HandleErrorAttribute),我们可以从全局过滤器中删除HandleErrorAttribute:

    public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new GlobalAuthorise());
        filters.Add(new OncHandleErrorAttribute());
        //filters.Add(new HandleErrorAttribute());
    }

基本上就是这样。您可以阅读更多详细信息,但对于这个想法,上面的内容就足够了。

我将尝试实现一个工作示例。如果您发现它不起作用或找到了不同的解决方案,请让我知道!我已经尝试过这个方法,但是当调用HandleJsonErrorAttribute OneException方法时,filterContext.ExceptionHandled属性始终为true,当操作所属的控制器类上存在HandleErrorAttribute时。操作方法是否应该优先处理错误并首先调用?上述方法在IISExpress中开发时起作用。为了使它在部署到真正的IIS Web服务器时工作,我们需要添加
context.HttpContext.Response.tryskipiiscustomerors=true当创建jsonmessage时,IIS otherwize会覆盖错误消息并显示其默认状态代码500页面