2014-06-13 7 views
8

Jak mogę zaimplementować filtry wyjątków w MVC5.Jak korzystać z filtrów wyjątków w MVC 5

Chcę rzucić wyjątek nlog i przekierować stronę domyślną stronę błędu, który wyświetla „Coś się popsuło”

Mam klasa filtra następująco

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"} 
      }); 

    } 
} 

}

Ale nic nie jest przekierowanie do strony ...

Odpowiedz

18

można czerpać swoją HandleErrorAttribute

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

następnie zarejestrować go globalnie

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

Domyślnie HandleErrorAttribute wyświetli widok Error znajdujący się w folderze ~/Views/Shared ale jeśli chcesz wyświetlić konkretny pogląd można ustawić właściwość atrybutu View .

+0

Gdzie powinienem umieścić tę klasę NLogExceptionHandlerAttribute? – TechNo

+0

@SajnaAli to tylko atrybut, taki sam jak wszystkie inne atrybuty w MVC, dlatego można go umieścić przeciwko akcji, kontrolerowi lub możesz zarejestrować go globalnie (czego najwyraźniej chcesz). Podałem przykład tego, jak to robisz. – James

+0

Istnieje już wiersz w_stokiem_starty w global.asax FilterConfig.RegisterGlobalFilters (GlobalFilters.Filters); czy powinniśmy dodać linię wspomnianą powyżej w pliku global.asax? pokazuje błędy: – TechNo

0

wierzę powinien być ten kod:

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

    } 

}

Możesz dodać dodatkowy „if (filterContext.ExceptionHandled!)” Oświadczenie przed zalogowaniu wartości wewnątrz rezultacie, aby upewnić się, że wyjątek jest na razie nieobsługiwany.