method - Deshabilitar estado de sesión por solicitud en ASP.Net MVC
mvc async view example (8)
Cambie DefaultCOntrollerFactory a la clase Custom ControllerFactory. Default Controller.TempDataProvider usa SessionStateTempDataProvider. Tú puedes cambiarlo.
1. Establecer web.config / system.web / sessionState: mode = "Off".
2.crear clase DictionaryTempDataProvider.
public class DictionaryTempDataProvider : ITempDataProvider
{
public IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
{
return new Dictionary<string, object>();
}
public void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
{
}
}
3.Crear diccionarioTempDataControllerFactory
public class DictionaryTempDataControllerFactory : DefaultControllerFactory
{
public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
var controller = base.CreateController(requestContext, controllerName) as Controller;
if (controller!=null)
controller.TempDataProvider = new DictionaryTempDataProvider();
return controller;
}
}
4.En el evento global.asax.cs Apprication_Start establece DictionaryTempDataControllerFactory.
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(
new DictionaryTempDataControllerFactory()
);
}
Estoy creando un ActionResult en ASP.Net MVC para servir imágenes. Con el estado de sesión habilitado, IIS solo manejará una solicitud a la vez del mismo usuario. (Esto es cierto no solo en MVC).
Por lo tanto, en una página con varias imágenes que llaman a esta Acción, solo se puede gestionar una solicitud de imagen a la vez. Es sincrónico.
Me gustaría que esta imagen Acción fuera asíncrona. Me gustaría que se ejecutaran varias solicitudes de imágenes sin necesidad de completar la anterior. (Si las imágenes fueran solo archivos estáticos, IIS las publicaría de esta manera).
Por lo tanto, me gustaría deshabilitar la sesión solo para llamadas a esa acción, o para especificar que ciertas solicitudes no tienen estado de sesión. Alguien sabe cómo se hace esto en MVC? ¡Gracias!
Crear un nuevo controlador
Decorar controler con [SessionState (SessionStateBehavior.Disabled)]
Código de refactorización que desea que se muestre deshabilitado para ese control
El atributo SessionState es bastante útil si usas mvc3. Cómo lograr esto con mvc2 necesita un poco más de codificación.
Idea es decirle al asp.net que la solicitud específica no usará el objeto de sesión.
Por lo tanto, crea un controlador de ruta personalizado para solicitudes específicas
public class CustomRouteHandler : IRouteHandler
{
public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
{
requestContext.HttpContext.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);
return new MvcHandler(requestContext);
}
}
SessionStateBehavior enum tiene 4 miembros, debes usar los modos "disabled" o "readonly" para obtener un comportamiento asincrónico.
Después de crear este controlador de ruta personalizado, asegúrese de que sus solicitudes específicas pasen por este controlador. Esto puede hacerse definiendo nuevas rutas en Global.asax
routes.Add("Default", new Route(
"{controller}/{action}",
new RouteValueDictionary(new { controller = "Home", action = "Index"}),
new CustomRouteHandler()
));
Agregar esta ruta hace que todas sus solicitudes sean manejadas por su clase de controlador de ruta personalizada. Puedes hacerlo específico definiendo diferentes rutas.
En nuestro servidor, IIS ni siquiera conoce las sesiones: es la pila ASP.NET que maneja una solicitud por sesión a la vez. Los archivos estáticos, como las imágenes, nunca se ven afectados.
¿Es posible que su aplicación ASP.NET esté publicando los archivos en lugar de IIS?
Intenta servir las imágenes de otro dominio. Así que algo así como images.mysite.com.
Esto le proporcionará dos beneficios: uno, las sesiones son rastreados por una cookie, por lo que images.mysite.com no tendrá la cookie. Dos, le dará dos solicitudes concurrentes adicionales para recuperar imágenes.
¿Has considerado configurar un HttpHandler para mostrar tus imágenes?
Si alguien está en la situación en que estaba, donde su controlador de imagen realmente necesita acceso de solo lectura a la sesión, puede poner el atributo SessionState en su controlador
[SessionState(SessionStateBehavior.ReadOnly)]
Consulte http://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute.aspx para obtener más información.
Gracias a https://.com/a/4235006/372926
También me encontré con el mismo problema y después de hacer I + D, este vínculo funcionó para mí. Referencia: https://techatfingers.wordpress.com/2016/06/14/session-state-on-action/
- Crear atributo personalizado
- Reemplazar el método "GetControllerSessionBehavior" presente en la clase DefaultControllerFactory.
- Registrarlo en global.aspx
1> Crear atributo personalizado
public sealed class ActionSessionStateAttribute : Attribute
{
public SessionStateBehavior SessionBehavior { get; private set; }
public ActionSessionStateAttribute(SessionStateBehavior sessionBehavior)
{
SessionBehavior = sessioBehavior;
}
}
2. Anular
public class SessionControllerFactory : DefaultControllerFactory
{
protected override SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
return SessionStateBehavior.Default;
var actionName = requestContext.RouteData.Values["action"].ToString();
Type typeOfRequest=requestContext.HttpContext.Request.RequestType.ToLower() =="get"?typeof(HttpGetAttribute):typeof(HttpPostAttribute);
// [Line1]
var cntMethods = controllerType.GetMethods()
.Where(m =>
m.Name == actionName &&
( ( typeOfRequest == typeof(HttpPostAttribute) &&
m.CustomAttributes.Where(a => a.AttributeType == typeOfRequest).Count()>0
)
||
( typeOfRequest == typeof(HttpGetAttribute) &&
m.CustomAttributes.Where(a => a.AttributeType == typeof(HttpPostAttribute)).Count() == 0
)
)
);
MethodInfo actionMethodInfo = actionMethodInfo = cntMethods != null && cntMethods.Count() == 1 ? cntMethods.ElementAt(0):null;
if (actionMethodInfo != null)
{
var sessionStateAttr = actionMethodInfo.GetCustomAttributes(typeof(ActionSessionStateAttribute), false)
.OfType<ActionSessionStateAttribute>()
.FirstOrDefault();
if (sessionStateAttr != null)
{
return sessionStateAttr.Behavior;
}
}
return base.GetControllerSessionBehavior(requestContext, controllerType);
}
3. Clase de registro en Global.asax
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// --- other code ---
ControllerBuilder.Current.SetControllerFactory(typeof(SessionControllerFactory));
}
}
En lugar de implementar un filtro de acción para esto, ¿por qué no implementa un RouteHandler
?
Aquí está el trato: IRouteHandler
tiene un método: GetHttpHandler
. Cuando realiza una solicitud ASP.Net MVC a un controlador, de forma predeterminada, el motor de enrutamiento maneja la solicitud creando una nueva instancia de MvcRouteHandler
, que devuelve un MvcHandler
. MvcHandler
es una implementación de IHttpHandler
que está marcada con la interfaz (¡sorpresa!) De IRequiresSessionState
. Esta es la razón por la cual una solicitud normal usa Session.
Si sigues la publicación de mi blog sobre cómo implementar un RouteHandler
personalizado (en lugar de utilizar MvcRouteHandler) para servir imágenes, puedes IHttpHandler
devolución de un IHttpHandler
etiquetado como IHttpHandler
.
Esto debería liberar a IIS de la imposición de la sincronicidad sobre usted. También es probable que sea más eficaz porque omite todas las capas del código MVC que trata sobre los filtros.