none
Controlar Timeout de la sesión RRS feed

  • Pregunta

  • Buenas,

    Cómo puedo hacer para que una aplicación MVC redireccione a un vista X cuando la session del usuario haya expirado. Actualmente el valor establecido está de la siguiente manera en un controlador:

    Session.Timeout = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings.Get("TimeOutSession"));

    Acaso debo verificar en el servidor cada vez que se haga un Get o Post??

    Gracias por alguna respuesta, saludos.

    domingo, 29 de marzo de 2015 20:29

Respuestas

  • deberías implementar tu propio ActionFilterAttribute para aplicarlo en cada acción Index de tus controladores.

    using System.Reflection;
    
    
    namespace miNamespace {
    
    
        public class SessionExpireFilterAttribute : ActionFilterAttribute {
    
    
            public override void OnActionExecuting( ActionExecutingContext filterContext ) {
                HttpContext ctx = HttpContext.Current;
    
    
                // check if session is supported
                if ( ctx.Session != null ) {
                    if ( ctx.Session.IsNewSession ) {
    
                        string sessionCookie = ctx.Request.Headers[ "Cookie" ];
                        if ( ( null != sessionCookie ) && ( sessionCookie.IndexOf ( "ASP.NET_SessionId" ) >= 0 ) ) {
    
    
                            ctx.Response.Redirect ( "~/Home/Login" );
                        }
                    }
                }
    
    
                base.OnActionExecuting ( filterContext );
            }
        }
    }

    luego aplicarlo a tu controller

    using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.Mvc;
        using System.Web.Mvc.Ajax;
    
        namespace Web.Controllers {
    
            public class HomeController : Controller {
    
                [SessionExpireFilter]
                public ActionResult Index( ) {
                    
                    return View();
                }
    
                public ActionResult Login() {
                    
                    return View();
                }
            }
        }


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    domingo, 29 de marzo de 2015 20:42
    Moderador
  • configuralo en el web.config. Doy por sentado que el modo es InProc

    <configuration>
      ...
      <system.web>
        <sessionState mode="InProc" timeout="5" />
      </system.web>
      ...
    </configuration>


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos


    domingo, 29 de marzo de 2015 21:41
    Moderador

Todas las respuestas

  • deberías implementar tu propio ActionFilterAttribute para aplicarlo en cada acción Index de tus controladores.

    using System.Reflection;
    
    
    namespace miNamespace {
    
    
        public class SessionExpireFilterAttribute : ActionFilterAttribute {
    
    
            public override void OnActionExecuting( ActionExecutingContext filterContext ) {
                HttpContext ctx = HttpContext.Current;
    
    
                // check if session is supported
                if ( ctx.Session != null ) {
                    if ( ctx.Session.IsNewSession ) {
    
                        string sessionCookie = ctx.Request.Headers[ "Cookie" ];
                        if ( ( null != sessionCookie ) && ( sessionCookie.IndexOf ( "ASP.NET_SessionId" ) >= 0 ) ) {
    
    
                            ctx.Response.Redirect ( "~/Home/Login" );
                        }
                    }
                }
    
    
                base.OnActionExecuting ( filterContext );
            }
        }
    }

    luego aplicarlo a tu controller

    using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.Mvc;
        using System.Web.Mvc.Ajax;
    
        namespace Web.Controllers {
    
            public class HomeController : Controller {
    
                [SessionExpireFilter]
                public ActionResult Index( ) {
                    
                    return View();
                }
    
                public ActionResult Login() {
                    
                    return View();
                }
            }
        }


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    domingo, 29 de marzo de 2015 20:42
    Moderador
  • Sergio, gracias por responder.

    He implementado la clase que me indicas y he agregado a los métodos de acción apropiados la anotación [SesionExpireFilter], de tal forma que se va a validar la sessión antes de entrar al método. Mi problema ahora está en que la Sessión contiene en el TimeOut el valor 20 y no lo que establecí en el controlador. Recuerdo que en asp.net 20 era el valor predeterminado para el timeout de la session pero lo reasignaba y no me daba problema, aquí no obecede y permanece siempre con el valor 20. ¿qué podría ser?

    Saludos y gracias,


    • Editado eduar2083 domingo, 29 de marzo de 2015 21:29
    domingo, 29 de marzo de 2015 21:29
  • configuralo en el web.config. Doy por sentado que el modo es InProc

    <configuration>
      ...
      <system.web>
        <sessionState mode="InProc" timeout="5" />
      </system.web>
      ...
    </configuration>


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos


    domingo, 29 de marzo de 2015 21:41
    Moderador
  • Correcto, lo he configurado directamente en el web.config y ya detecta el valor. Una última duda Sergio: dentro de la clase implementada SessionExpireFilterAttribute, en la linea:

    string sessionCookie = context.Request.Headers["Cookie"];

    Siempre retorna null (con o sin session expirada) y por ende nunca entra para redireccionar el Response.

    Saludos.

    domingo, 29 de marzo de 2015 22:00
  • Hola. Reiniciaste tu servidor web? Usas IIS?

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    domingo, 29 de marzo de 2015 22:48
    Moderador
  • Hola Sergio, aún estoy en fase de desarrollo. Estoy usando el servidor de Visual Studio.

    Saludos.

    domingo, 29 de marzo de 2015 22:53
  • Correcto, lo he configurado directamente en el web.config y ya detecta el valor. Una última duda Sergio: dentro de la clase implementada SessionExpireFilterAttribute, en la linea:

    string sessionCookie = context.Request.Headers["Cookie"];

    Siempre retorna null (con o sin session expirada) y por ende nunca entra para redireccionar el Response.

    Saludos.


    pon un punto de ruptura y verifica también el contenido en Request.Cookies.

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    domingo, 29 de marzo de 2015 23:07
    Moderador
  • La coleccion no contiene elementos:



    Estaba pensando que quizás haya que configurar el atributo cookieless de sessionState.
    • Editado eduar2083 lunes, 30 de marzo de 2015 0:13
    lunes, 30 de marzo de 2015 0:11
  • El ejemplo aplica cuando tienes como modo de autenticación a Forms. Crea un proyecto nuevo de MVC con la plantilla Internet Template. Haces Login, registras un usuario y verás que ya tienes la cookie de autenticación.


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó vótala como útil. Saludos

    lunes, 30 de marzo de 2015 7:16
    Moderador
  • Había olvidado mencionar que la aplicación tiene autenticación Windows y no debo modificarla para que haga login por formulario. ¿Entonces lo implementado no me servirá, o en todo caso qué opción tengo para controlar la  sesión en una aplicación Web para Intranet?

    Saludos.

    lunes, 30 de marzo de 2015 17:21
  • Hola, disculpen por resucitar este tema. Sucede que la cookie no se creaba porque no le estaba agregando elemento alguno a la Session, al parecer, la Session debe contener por lo menos un elemento para que la cookie se cree. Hasta aquí todo estaba yendo bien, el método que verifica la sesión tiene la siguiente forma:

    public class SessionExpireFilterAttribute : ActionFilterAttribute
    {
    	public override void OnActionExecuting(ActionExecutingContext filterContext)
    	{
    		HttpContext context = HttpContext.Current;
    
    		// check if session is supported
    		if (context.Session != null)
    		{
    			// check if a new session id was generated
    			if (context.Session.IsNewSession)
    			{
    				// If it says it is a new session, but an existing cookie exists, then it must
    				// have timed out
    				string sessionCookie = context.Request.Headers["Cookie"];
    				var reqCook = context.Request.Cookies;
    
    				if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
    					context.Response.Redirect("~/Ingresar/Index", true);
    			}
    		}
    
    		base.OnActionExecuting(filterContext);
    	}
    }

    Se redirecciona correctamente a Ingresar/Index cuando la sesión ha caducado y se realiza una petición tipo GET, es decir, cuando se invoca a cualquier Vista, sin embargo, no redirecciona cuando después de caducada la sesión se realiza una petición POST ha pesar que veo que se ejecuta la línea:

    context.Response.Redirect("~/Ingresar/Index", true);

    Favor su apoyo, muchas gracias,

    Saludos.

    martes, 30 de junio de 2015 18:16