.Net MVC例外處理

.Net MVC 六種處理exception的方式

1. 使用try catch

public ActionResult ErrorPage()
{
    try
    {
        ......;
    }
    catch(Exception ex)
    {
        return View("Error");
    }
}
這種方法會產生散彈式修改,例外處理策略一改變會疲於奔命 (X)

2. 在Controller複寫OnException

public class TheController : Controller
{
   protected override void OnException(ExceptionContext filterContext)
   {
      Exception ex = filterContext.Exception;
      filterContext.ExceptionHandled = true;

      var data = new ViewDataDictionary();
      data["ErrorMessage"] = ex.Message;
      filterContext.Result = new ViewResult()
      {
        ViewName = "Error",
        ViewData = data
      };
   }
}
1. 這種方法也會產生散彈式修改,但修改處集中在Controller            (X)
2. 如果不使用繼承,會造成重複程式碼                                (X)
3. 如果使用了繼承,則造成侵入式耦合,所有Controller背負額外的負擔    (X)

3. 使用Web.config

<system.web>
   <customErrors mode="On" defaultRedirect="Error">
   <error statusCode="404" redirect="~/Error"/>
   </customErrors>
</system.web>
1. Web.config 相依於執行環境,不能使用在.net mvc 6.0  (X)
2. 例外處理脫離正常流程                               (X)
3. 難以客製化不同例外的處理方式                      (X)

4. Global.asax

public class MvcApplication : System.Web.HttpApplication
{
   protected void Application_Error(object sender, EventArgs e)
   {
      Exception exception = Server.GetLastError();
      Server.ClearError();
      Response.Redirect("/Error/Index");
   }
}
1. 與第三項類似,差別在於此處是使用c#作組態化

5. 使用HandleError

public class TheController : Controller
{
   [HandleError(ExceptionType=typeof(DbUpdateException),View="Error1")]
   [HandleError(ExceptionType = typeof(DbEntityValidationException),View ="Error2")]
   public ActionResult ErrorPage()
   {

   }
}
1. 不同例外可對應不同錯誤頁面                (O)
2. 例外被侷限在正常處理流程,方便Trace code   (O)
3. 如果處理策略統一,會造成重複的程式碼       (X)

6. 使用客製化Exception Handle Attribute

public class ExceptionHandleAttribute : HandleErrorAttribute,
IVistor<DbEntityValidationException, DbUpdateException>
{
   private string errorMessage = string.Empty;
   public override void OnException(ExceptionContext context)
   {
      context.Exception.Accept(this);
      context.ExceptionHandled = true;

      data["ErrorMessage"] = message;
      context.Result = new ViewResult()
      {
        ViewName = "Error",
        ViewData = data
      };
   }

   public void visit(DbUpdateException ex)
   {
      errorMessage = "error# 0 ===>" + ex.Parser();
   }

   public void visit(DbEntityValidationException ex)
   {
      errorMessage = "error# 1 ===>" + ex.Parser();
   }
}

public class HomeController : Controller
{
   [ExceptionHandle]
   public ActionResult SomeError()
   {

   }
}
1. 不同例外可對應不同錯誤處理方式              (O)
2. 例外被侷限在正常處理流程,方便Trace code     (O)
3. 如果處理策略統一,可重複使用同一個Attribute  (O)
4. 處理策略改變,只要修改一個地方即可           (O)