九月第一篇,呵呵
前言:最近剛入職了一家公司,上司讓我維護一個項目,我接手了看了一下項目,try catch 嚴重影響我的視覺,我直接通過vs插件将其try catch全部替換掉占位符,呵呵。
是以我特此寫了這篇文章...
正本:有可能你在搞開發的時候在每個子產品中都要try catch,這樣不僅不優雅也非常累,看了這篇文章,你會有所收獲,你将會從50行代碼收縮成30行.當然這取決于你的邏輯。
在CustomHandlerErrorAttribute中要繼承HandleErrorAttribute
HandleErrorAttribute.cs
#region 程式集 System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
#endregion
namespace System.Web.Mvc
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class HandleErrorAttribute : FilterAttribute, IExceptionFilter
{
public HandleErrorAttribute();
public Type ExceptionType { get; set; }
public string Master { get; set; }
public override object TypeId { get; }
public string View { get; set; }
public virtual void OnException(ExceptionContext filterContext);
}
}
人們常說虛方法都是可以重寫的,也就是說你可以去擴充它.看代碼CustomHandlerErrorAttribute.cs

為什麼我在這裡截圖呢,我是害怕别人複制黏貼,當然這不是我小氣,因為很多人百度 都太懶了,也希望你們尊重部落客的勞動成功
這樣隻要程式抛出異常,或者錯誤就換到自定義錯誤過濾器,這種形式也可以叫做短路器,當然不隻是包括action的行為,如果是ajax請求報錯,我們直接傳回json,例如伺服器崩掉。我們看一下測試過程。為了測試友善我直接把IIS啟動起來了。
我們先看一下最簡單的出錯:
public ActionResult ExceptionUnCatch()
{
throw new Exception("ExceptionCatch");
return View();
}
@{
ViewBag.Title = "ExceptionUnCatch";
}
<h2>ExceptionUnCatch</h2>
結果
經過測試也是成功跳入我的自定義錯誤過濾器,通過給action添加特性,才會使ASP.NET MVC 的生命周期中包括了我的過濾器。但是我們看另一種情況.我們加上try catch 呢?
public ActionResult ExceptionCatch()
{
try
{
throw new Exception("ExceptionCatch...");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return View();
}
視圖方面:
@{
ViewBag.Title = "ExceptionCatch";
}
<h2>ExceptionCatch</h2>
可以發現錯誤被catch掉了,那如果我們在頁面中抛出了異常呢.我們不去說view中會出什麼異常,直接在代碼中添加代碼塊<h1>@{throw new Exception("Exception View");}</h1>,經過我的測試,它也是成功的傳回錯誤資訊。
自習看過我的代碼你會發現我在過濾器中添加了一個ajax請求的異常處理,我們簡單的測試一下.在視圖上定義了一個action 裡面指向參數 我并沒有那些控制器或action!!<h1>@Html.ActionLink("asdsa","asdsa")</h1>
結果
最後在FilterConfig.cs中對所有action生效
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
//filters.Add(new CustomAuthorizeAttribute());//3 全局注冊,全部的控制器/action都生效
filters.Add(new CustomHandlerErrorAttribute());//
}
但是處理不到的情況就有了,例如在控制器構造函數中抛出異常或者說通路的url不存在
總來來說是因為它們是管道級别錯誤,不屬于acton行為級别 ,這種情況我們隻能借助配置項來對錯誤進行封裝
在system.web中添加
<customErrors mode="On" defaultRedirect="~/Demo.html">
<error statusCode="404" redirect="~/Demo.html"/>
</customErrors>
另一種方式可以在global.asax.cs中添加Application.error或許你應該懂了吧?
protected void Application_Error(object sender,EventArgs args)
{
var errorDetail = Server.GetLastError();
Context.Response.Write(errorDetail);
Server.ClearError();
}
總結:使用自定義錯誤過濾器配合全局錯誤就可以達到非常好的錯誤處理。