2013-09-22 3 views
0

У меня есть приложение ASP.NET MVC4. Я создал страницу входа. Если пользователь входит в систему, я регистрирую информацию пользователя на сеансе. Я добавил фильтр для проверки переменной сеанса. Если пользователь не входил в систему, я хочу перенаправить пользователя на мой контроллер входа.ASP.NET MVC4 ActionFilters

public class SecurityAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (filterContext.HttpContext.Session["User"] == null) 
      { 
       filterContext.HttpContext.Response.RedirectToRoute("Default", new 
       { 
        controller = "Login", 
        action = "DoLogin", 
        returnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri 
       }); 
      } 
      base.OnActionExecuting(filterContext); 
     } 
    } 

Я использую этот атрибут на уровне контроллера.

[SecurityAttribute] 
    public class HomeController : Controller 
    { 
     public ActionResult Index() 
     { 
      ViewData["Name"] = ((UserEntity)Session["User"]).Name; 
      ViewData["Surname"] = ((UserEntity)Session["User"]).Surname; 
      return View(); 
     } 
    } 

метод OnActionExecuting срабатывает перед действием выполнения, но перенаправление после метода встречается, действия в моем родном контроллере. Поскольку переменная session имеет значение null, я получаю ошибку в действии индекса. Как я могу это исправить?

ответ

2

Вы должны назначить свойство Result на filterContext, если вы хотите закоротить выполнение действия контроллера. Просто так:

public class SecurityAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (filterContext.HttpContext.Session["User"] == null) 
     { 
      var values = new 
      { 
       controller = "Login", 
       action = "DoLogin", 
       returnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri 
      }; 
      var result = new RedirectToRouteResult("Default", new RouteValueDictionary(values)); 

      filterContext.Result = result; 
     } 
    } 
} 

Кроме того, было бы семантически правильнее написать фильтр авторизации для этой цели, и полагаться на встроенную проверку подлинности форм, а не изобретать колеса с сессии и прочее.

Так просто:

[Authorize] 
public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     string username = User.Identity.Name; 
     SomeUserModel user = GetUserFromBackend(username); 
     return View(user); 
    } 
} 

Вы можете прочитать больше о подлинности с помощью форм в MSDN: http://msdn.microsoft.com/en-us/library/ff647070.aspx