9

Mam nadpisanie kontrolera, który sprawdza, czy istnieją określone dane sesji. Te dane są wymagane, aby repozytorium działało poprawnie, więc jeśli nie istnieje, to po sprawdzeniu użytkownik powinien się wylogować.Przekierowanie z kontrolera Inicjowanie nie działa

protected override void Initialize(System.Web.Routing.RequestContext requestContext) 
{ 
    base.Initialize(requestContext); 
    if (Session["CompanyID"] != null) 
    { 
     repo.CompanyID = (long)Session["CompanyID"]; 
    } 
    else 
    { 
     RedirectToAction("LogOff", "Account"); 
    } 
} 

Mój kod wygląda tak, ale nawet gdy RedirectToAction jest wywoływany sterownik nadal otwiera domyślną akcję, a użytkownik nie jest wylogowany. Czy możesz polecić, jak rozwiązać ten problem?

Używam danych sesji w taki sposób, ponieważ jest to pierwsze miejsce, w którym mogę uzyskać dostęp do tego, co wiem i tutaj mogę sprawdzić, czy te konkretne dane istnieją. Jest zapisywany, gdy użytkownik się loguje.

Dane te są częścią użytkownika w bazie danych. Zrobiłem niestandardowy dostawca członkostwa i ról. Czy istnieje sposób na dodanie tych danych do "Użytkownika" typu MembershipUser w jakiś sposób, aby można było uzyskać do niego dostęp w konstruktorze, takim jak nazwa użytkownika?

Odpowiedz

12

Zamiast tego rozważ użycie niestandardowego ActionFilter.

public class HasCompanyIdAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (filterContext.HttpContext.Session["CompanyID"] == null) 
     { 
      filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {action = "LogOff", controller = "Account"})); 
     } 
    } 
} 

To może być następnie stosowane jako tak:

[HasCompanyId] 
public class MyController : Controller 
{ 
    public ActionResult SomeAction() 
    { 
     return View(); 
    } 
} 

ten będzie miał zastosowanie atrybutu dla wszystkich żądań, które MyController (lub jej podklasy) uchwyty.

+0

Rozumiem zasadę, ale wydaje się nieco niepraktyczna. Nie mogę uczynić go filtrem globalnym, ponieważ istnieją publiczne obszary zastosowania, a następnie muszę zastosować je do każdego działania znajdującego się w obszarze, który tego wymaga? Czy istnieje jakiś inny sposób na przerwanie ładowania kontrolera po inicjalizacji i wysłanie go do innej akcji innego kontrolera? – Zaak

+0

Możesz zastosować atrybut do kontrolera i zostanie on zastosowany do każdej akcji w tym kontrolerze lub do klasy bazowej kontrolera, a następnie akcja zostanie zastosowana dla wszystkich pochodnych działań klas! –

+0

Hmm, w ten sposób nie rozwiązuje się faktu, że muszę go ustawić raz. Wydaje się, że robienie rzeczy poprzez FilterAttribute w ten sposób ustawiałoby go za każdym razem, gdy akcja wykonywana byłaaby tylko wtedy, gdy tworzony jest kontroler? – Zaak

2

Po prostu zaimplementuj rozwiązanie, zastępując OnActionExcuting w klasie bazowej. Następnie możesz zrobić wszystko, co możesz zrobić w Filarze akcji. Tak jak poniżej:

public void OnActionExecuting(ActionExecutingContext filterContext){ 
    if (filterContext.HttpContext.Session["CompanyID"] != null) 
    repo.CompanyID = (long)filterContext.HttpContext.Session["CompanyID"]; 
    else 
    filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {action = "LogOff", controller = "Account"})); 
} 

Część kodu pominięto dla zwięzłości.

Próbowałem obu podejść i stwierdziłem, że wdrożenie go za pomocą filtra akcji było bardziej złożone ze względu na wymagania dotyczące wtrysku zależnego, które miałem. Możesz to zrobić w dowolny sposób, ale uznałeś, że podejście oparte na klasie bazowej było nieco jaśniejsze. Chciałem również ustawić niektóre właściwości klasy bazowej, aby udostępnić kilka standardowych obiektów metodom kontrolera, aby zapisać powtarzające się kody, które DEV dodawały do ​​akcji. Podejście klas bazowych ułatwiło to.

Jedno zastrzeżenie, które dodam, nie sugeruję, że jest to dobre podejście do uwierzytelniania/bezpieczeństwa, patrzę na to wyłącznie z perspektywy chęci wykonania niektórych operacji/walidacji przed wykonaniem akcji i również konfigurowanie niektórych wstępnie wypełnionych danych na temat instancji kontrolera, zgodnie z zasadą DRY.

Mam nadzieję, że to pomaga.

Powiązane problemy