2014-06-13 20 views
8

如何在MVC5中实现异常过滤器。如何在MVC 5中使用异常过滤器

我想抛出异常NLOG和页面重定向到显示“有什么东西出了问题”

我有一个过滤器类,如下所示

using System; 
using System.Diagnostics; 
using System.Security.Policy; 
using System.Web.Mvc; 
using System.Web.Mvc.Filters; 
using System.Web.Routing; 
using System.Web.UI.WebControls; 
using Delivros.UI.Controllers; 
using Delivros.UI.Areas.User.ViewModel; 
using System.Web; 

namespace Delivros.UI.Filters 
{ 

public class CustomAuthenticationFilter : IAuthenticationFilter 
{ 
    public void OnAuthentication(AuthenticationContext filterContext) 
    { 

    } 

    public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) 
    { 
     Debug.WriteLine("OnAuthenticationChallenge : MyAuthenticationFilter"); 
    } 
} 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class MyAuthorizationFilter : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (filterContext.RequestContext.HttpContext.Request.Cookies[System.Configuration.ConfigurationManager.AppSettings[Convert.ToString(CookieField.cookieName)]] == null) 
     { 

     } 
     else 
{ 
      filterContext.Result = new RedirectToRouteResult(
      new RouteValueDictionary 
    { 
       { "controller", "User" }, 
       { "action", "UserRegistration" } , 
       {"Area","User"} 
      }); 

     } 
    } 
} 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class CustomActionFilter : ActionFilterAttribute 
{ 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1)); 
     filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false); 
     filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); 
     filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
     filterContext.HttpContext.Response.Cache.SetNoStore(); 
     base.OnResultExecuted(filterContext); 
     filterContext.Result = new RedirectToRouteResult(
       new RouteValueDictionary 
      { 
       { "controller", "User" }, 
       { "action", "UserRegistration" } , 
       {"Area","User"} 
      }); 
     // ActionResult home = new HomeController().Index();   
    } 
} 

public class MyResultFilter : IResultFilter 
{ 
    public void OnResultExecuting(ResultExecutingContext filterContext) 
    { 

    } 

    public void OnResultExecuted(ResultExecutedContext filterContext) 
    { 

    } 
} 

public class MyExceptionFilter : IExceptionFilter 
{ 
    public void OnException(ExceptionContext filterContext) 
    { 
     filterContext.Result = new RedirectToRouteResult(
       new RouteValueDictionary 
      { 
       { "controller", "User" }, 
       { "action", "UserLogOut" } , 
       {"Area","User"} 
      }); 

    } 
} 

}

默认的错误页面

但是没有东西重定向到页面...

回答

18

您可以派生自己的HandleErrorAttribute

public class NLogExceptionHandlerAttribute : HandleErrorAttribute 
{ 
    public override void OnException(ExceptionContext filterContext) 
    { 
     // log error to NLog 
     base.OnException(filterContext); 
    } 
} 

然后将其注册在全球

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
    filters.Add(new NLogExceptionHandlerAttribute()); 
    ... 
} 

默认情况下,HandleErrorAttribute将显示地处~/Views/Shared文件夹中的Error看法,但如果你想显示特定视图中,您可以设置该属性的View财产。

+0

我应该在哪里放这个类NLogExceptionHandlerAttribute? – TechNo

+0

@SajnaAli它只是一个属性,与MVC中的所有其他属性相同,因此它可以针对操作,控制器放置,或者可以在全局注册(这是您似乎想要的)。我提供了一个如何做到这一点的例子。 – James

+0

global.asax中的application_start中已有一行 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 我们应该在global.asax文件中添加上面提到的那一行吗? 它显示错误 – TechNo

0

我相信它应该是这样的代码:

public class MyExceptionFilter : IExceptionFilter 
{ 
    public void OnException(ExceptionContext filterContext) 
    { 
     filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { 
      action = "UserLogOut", 
      controller = "User", 
      area = "User" 
     })); 

    } 

}

你可以加一个额外的“如果(filterContext.ExceptionHandled!)”语句之前记录的结果里面的值,以确保这个例外情况目前尚未处理。