2008-10-13 12 views
5

我試圖讓我的頭在MVC中的錯誤處理。 我正在尋找的是一種集中的方式來捕捉錯誤,記錄它們,如果可能的話解決它們,如果nessecary採取其他行動,並最終向用戶顯示正確的看法。ErrorController處理錯誤,而不是直接查看

我想我可以使用[HandleError]過濾器,但我沒有看到任何方式將它路由到控制器/操作。我看到的唯一選擇是將其直接指向視圖。

回答

4

HandleErrorAttribute MVC自帶的是一個非常基本的IExceptionFilter。

你有幾個選擇來實現我認爲你想要的。

您可以使用[的HandleError(類型= typeof運算(MyException),查看= 「ErrorView」)上的動作/控制器或實現自己的

HandleErrorAttribute心不是很複雜。我認爲MS建議您複製此代碼並進行修改以適應您的要求。

通過OnException覆蓋,您可以通過ExceptionContext訪問您可能需要的所有信息 - 控制器,操作,路由數據等。

記得設置ExceptionHandled。然後,您可以將filterContext.Result設置爲一個新的RedirectToAction實例,該實例將重定向到您的ErrorController和動作 - 顯然,您可以使用屬性公開具體的控制器和動作。

+0

標準HandleError不允許我路由到控制器,我認爲。所以這不是我需要的。 我想我必須自己推出自己的產品。 不要碰巧有什麼好的材料可以參考嗎? – 2008-10-13 12:49:39

+0

是的,http://haacked.com/archive/2008/08/14/aspnetmvc-filters.aspx – CVertex 2008-10-13 14:24:24

1

爲什麼不從自己的ActionResult派生出你自己的ErrorResult?

0

我在做什麼(可能是也可能不是一個很好的做法)是這樣的:

當發生錯誤:

  • 如果我所料,並可以處理它,怎麼辦?(與ELMAH)
  • 如果我所料,並不能處理它,我就登錄到ELMAH和返回的ViewResult這是我的錯誤頁面
    • 包括錯誤的描述,一個標準的消息和記錄它鏈接回我什麼在做
  • 如果我沒想到吧,我在我的基地控制器類的OnError的覆蓋不上一步驟
  • 不能處理由ELMAH都會被自動記錄所有其他錯誤,並請求yellowscreens

我的大多數通用錯誤處理都在我的所有控制器的基類中。唯一的問題是我必須在基類中手動設置控制器和操作值,以便它可以在錯誤頁面中爲重定向生成ActionLink。

2

Leppi,如果您想發送到操作結果,您可以定義操作和控制器以重定向錯誤。這是一個很好的例子,但是我個人不喜歡沒有使用自定義頁面或http代碼來代碼

這裏是我的IExtenptionFilter的例子。我的基地控制器有一個默認的IExceptionFilter處理所有沒有控制錯誤。

[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", 
    Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")] 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 
public class GenericExceptionHandlerFilter : ActionFilterAttribute, IExceptionFilter 
{ 

    public Type ExceptionType { get; set;} 
    public string RedirectToAction { get; set;} 
    public string RedirectToController { get; set;} 

    protected bool ApplyFilter(ExceptionContext filterContext) 
    { 
     Type lExceptionType = filterContext.Exception.GetType(); 
     return (ExceptionType == null || 
       lExceptionType.Equals(ExceptionType)); 
    } 


    #region IExceptionFilter Members 
    public void OnException(ExceptionContext filterContext) 
    { 

     if (ApplyFilter(filterContext)) 
     { 
      IbfControllerLogger.Log(filterContext.Exception); 

      filterContext.ExceptionHandled = true; 

      #region Calculate Action Controller Error 
      RouteValueDictionary lRoutes = new RouteValueDictionary(new 
       { 
        action = RedirectToAction, 
        controller = String.IsNullOrEmpty(RedirectToController) ? (string)filterContext.RouteData.Values["controller"] : RedirectToController 
       }); 
      UrlReWriterUtils.UrlReWriter(filterContext.Controller.ViewData, lRoutes); 
      #endregion 

      filterContext.Controller.TempData[TempDataName.C_TEMPDATA_EXCEPTIONERROR] = filterContext.Exception; 
      filterContext.Result = new RedirectToRouteResult(lRoutes); 
     } 
    } 
    #endregion