Bên trong Global.asax của bạn, bạn có phương thức sau:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
Điều này đăng ký HandleErrorAttribute làm bộ lọc hành động chung. Điều này có nghĩa là trình xử lý này được tự động áp dụng cho tất cả các hành động của bộ điều khiển. Bây giờ chúng ta hãy xem cách thuộc tính này được triển khai bằng cách xem mã nguồn:
[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 HandleErrorAttribute : FilterAttribute, IExceptionFilter {
private const string _defaultView = "Error";
private readonly object _typeId = new object();
private Type _exceptionType = typeof(Exception);
private string _master;
private string _view;
public Type ExceptionType {
get {
return _exceptionType;
}
set {
if (value == null) {
throw new ArgumentNullException("value");
}
if (!typeof(Exception).IsAssignableFrom(value)) {
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
MvcResources.ExceptionViewAttribute_NonExceptionType, value.FullName));
}
_exceptionType = value;
}
}
public string Master {
get {
return _master ?? String.Empty;
}
set {
_master = value;
}
}
public override object TypeId {
get {
return _typeId;
}
}
public string View {
get {
return (!String.IsNullOrEmpty(_view)) ? _view : _defaultView;
}
set {
_view = value;
}
}
public virtual void OnException(ExceptionContext filterContext) {
if (filterContext == null) {
throw new ArgumentNullException("filterContext");
}
if (filterContext.IsChildAction) {
return;
}
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) {
return;
}
Exception exception = filterContext.Exception;
if (new HttpException(null, exception).GetHttpCode() != 500) {
return;
}
if (!ExceptionType.IsInstanceOfType(exception)) {
return;
}
string controllerName = (string)filterContext.RouteData.Values["controller"];
string actionName = (string)filterContext.RouteData.Values["action"];
HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
filterContext.Result = new ViewResult {
ViewName = View,
MasterName = Master,
ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
TempData = filterContext.Controller.TempData
};
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
Mã nguồn chứa các bình luận và không chỉ là tự giải thích. Điều đầu tiên nó kiểm tra là bạn đã bật lỗi tùy chỉnh trong web.config của mình (tức là <customErrors mode="On">
). Nếu bạn không có nó thì không có gì => YSOD. Nếu bạn đã bật lỗi tùy chỉnh thì chế độ xem Lỗi sẽ chuyển cho nó một mô hình có chứa ngăn xếp ngoại lệ và thông tin hữu ích khác.