9

Tengo un reemplazo para el controlador que comprueba si existen ciertos datos de sesión. Esta información es necesaria para que el repositorio funcione correctamente, por lo tanto, si no existe, después de la verificación el usuario debe cerrar la sesión.Redirigir desde el controlador Inicializar no funciona

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

Mi código es el siguiente, pero incluso cuando se invoca el RedirectToAction el controlador todavía se abre la acción predeterminada y el usuario no está dado de baja. ¿Puede recomendarnos cómo manejar este problema?

Estoy utilizando esta información de sesión de tal manera porque este es el primer lugar que puedo conocer y aquí puedo verificar si existe esta información en particular. Se escribe cuando el usuario inicia sesión.

Estos datos forman parte del usuario en la base de datos. Creé una membresía personalizada y un proveedor de roles. ¿Hay alguna manera de agregar estos datos a "Usuario" de MembershipUser de alguna manera para que se pueda acceder en el constructor como usuarios?

Respuesta

12

Considere el uso de un ActionFilter personalizado en su lugar.

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

A continuación, se puede aplicar como tal:

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

Esto se aplicará el atributo para todas las solicitudes que (o que es subclases) maneja myController.

+0

Entiendo el principio, pero parece un poco poco práctico. No puedo convertirlo en un filtro global ya que hay áreas públicas de aplicación, y luego tengo que aplicarlo a cada acción que se encuentre dentro del área que lo requiera. ¿Hay alguna otra manera de interrumpir la carga del Controlador después de inicializarlo y enviarlo a otra acción de otro Controlador? – Zaak

+0

Puede aplicar el atributo a un controlador, y se aplicará para cada acción dentro de ese controlador, o una clase base de controlador y luego la acción se aplicará para cada acción de clases derivadas también. –

+0

Hmm, de esta manera todavía no aborda el hecho de que tengo que configurarlo una vez. Parece que hacer cosas a través de FilterAttribute de esta manera lo establecería cada vez que una acción se ejecute en su lugar solo cuando se crea una instancia del controlador? – Zaak

2

Simplemente implemente su solución anulando OnActionExcuting en la clase base en su lugar. Luego puede hacer todo lo que puede hacer en el filtro de acción. De la misma manera:

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

Se omite algún código para abreviar.

Probé ambos enfoques y descubrí que implementarlo a través de un filtro de acción era más complejo debido a los requisitos de Inyección de Dependencia que tenía. Puedes hacerlo de cualquier manera, pero sentí que el enfoque de la clase base era un poco más claro. También quería establecer algunas propiedades en la clase base para poner algunos objetos estándar a disposición de los métodos del controlador para guardar el código repetitivo que los DEV agregaban a las acciones. El enfoque de la clase base lo hizo fácil.

Una advertencia que voy a agregar es que no estoy sugiriendo que este sea un buen enfoque de autenticación/seguridad, estoy mirando esto solo desde la perspectiva de querer realizar algunas operaciones/validación antes de una acción de ejecución y también configurando algunos datos pre-poblados en la instancia del controlador para seguir el principio DRY.

Espero que ayude.

Cuestiones relacionadas