2008-09-21 75 views
9

aspnet mvc具有HandleError過濾器,如果發生錯誤將返回視圖,但如果在調用JsonResult時發生錯誤操作如何返回表示錯誤的JSON對象?如何從HandleError過濾器返回JSON?

我不想在每個操作方法中返回一個try/catch中的JsonResult來完成它的代碼,我寧願通過添加'HandleJsonError'屬性或使用現有的HandleError屬性來實現它所需的操作方法。

回答

9

看看HandleErrorAttribute的MVC實現。它返回一個ViewResult。你可以編寫你自己的版本(HandleJsonErrorAttribute),它返回一個JsonResult。

+0

我試過這個,但是當HandleJsonErrorAttribute的OnException方法被調用時,filterContext.ExceptionHandled屬性總是爲true,當這個動作屬於Controller類的HandleErrorAttribute時。不應該採取行動方法handleerror優先,並首先被調用? – 2008-09-21 21:43:02

1

也許你可以創建自己的屬性,並有一個構造函數值,該值需要View或Json的枚舉值。以下是我使用自定義授權屬性來演示我的意思。通過這種方式,當身份驗證在json請求上失敗時,它會響應一個json錯誤,如果它返回一個View,則返回相同的結果。

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() 
    { 
    } 
+0

我將嘗試並實施一個工作示例。如果你發現它不工作或找到不同的解決方案,請讓我知道! – Vyrotek 2008-09-21 01:10:20

7

總之,要走的路可以延長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); 
    } 

我在上面添加一些票證信息,您可以忽略此。由於過濾器的實現方式(擴展了默認HandleErrorAttributes),我們可以從全局過濾器然後取出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()); 
    } 

這基本上是它。你可以閱讀my blog entry以獲得更詳細的信息,但對於這個想法,上面應該足夠了。

+2

在IISExpress中開發上述工作。爲了在部署到真正的IIS web服務器時工作,我們需要在創建我們的jsonmessage時添加`context.HttpContext.Response.TrySkipIisCustomErrors = true;因爲IIS otherwize覆蓋了錯誤消息並顯示其默認狀態代碼500頁 – mortb 2015-09-22 10:12:29