Domanda

Sto creando un ActionResult in ASP.Net MVC per servire le immagini. Con stato sessione abilitata, IIS gestirà solo una richiesta alla volta dallo stesso utente. (Questo è vero non solo in MVC.)

Pertanto, in una pagina con più immagini di richiamare a questa azione, solo una richiesta di immagine può essere gestita in un momento. E 'sincrona.

Mi piacerebbe questa immagine Azione di essere asincrono - Vorrei richieste multiple di immagine per ciascuna eseguire senza bisogno di quella precedente per il completamento. (Se le immagini erano solo i file statici, IIS li servire in questo modo.)

Così, mi piacerebbe disabilitare sessione solo per le chiamate a tale azione, o per specificare che alcune richieste non hanno stato sessione. Qualcuno sa come questo è fatto in MVC? Grazie!

È stato utile?

Soluzione

Invece di implementare un filtro d'azione per questo, perché non si implementa un RouteHandler?

Ecco il punto - IRouteHandler ha un metodo - GetHttpHandler. Quando si effettua una richiesta di ASP.Net MVC a un controller, per impostazione predefinita il motore di routing gestisce la richiesta con la creazione di una nuova istanza di MvcRouteHandler, che restituisce un MvcHandler. MvcHandler è un'implementazione di IHttpHandler che è contrassegnato con il (sorpresa!) Interfaccia IRequiresSessionState. Questo è il motivo per cui una richiesta normale usa sessione.

Se seguite il mio post sul blog su come implementare un RouteHandler personalizzato (invece di utilizzare MvcRouteHandler) per servire le immagini - si può saltare la restituzione di un session-tagged IHttpHandler.

Questo dovrebbe liberare IIS dall'imporre sincronicità su di voi. Sarebbe anche probabilmente più performante perché è saltare tutti gli strati del codice MVC trattare con i filtri.

Altri suggerimenti

Se qualcuno si trova nella situazione mi trovavo, in cui il controller immagine in realtà ha bisogno di accesso in sola lettura alla sessione, si può mettere l'attributo SessionState sul controller

[SessionState(SessionStateBehavior.ReadOnly)]

http://msdn.microsoft.com /en-us/library/system.web.mvc.sessionstateattribute.aspx per maggiori informazioni.

Grazie alla https://stackoverflow.com/a/4235006/372926

Ho anche incontrato lo stesso problema e dopo aver fatto la R & S questo link ha lavorato per me Riferimento: https://techatfingers.wordpress.com/2016/06/ 14 / sessione di-stato-on-action /

  1. Crea attributo personalizzato
  2. Sostituisci il “GetControllerSessionBehavior” metodo presente nella classe DefaultControllerFactory.
  3. Registrati è in global.aspx

1> Crea attributo personalizzato

public sealed class ActionSessionStateAttribute : Attribute
    {
            public SessionStateBehavior SessionBehavior { get; private set; }          
            public ActionSessionStateAttribute(SessionStateBehavior sessionBehavior)
            {
                SessionBehavior = sessioBehavior;
            }
    }

2. Ignora

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. Registrati classe nel Global.asax

public class MvcApplication : System.Web.HttpApplication
 {
        protected void Application_Start()
        {
            // --- other code ---
            ControllerBuilder.Current.SetControllerFactory(typeof(SessionControllerFactory));
        }
}

Prova servire le immagini da un altro dominio. Quindi, qualcosa di simile a images.mysite.com.

Questo vi fornirà due vantaggi: uno, le sessioni sono tracciati da un cookie, in modo da images.mysite.com non avrà il cookie. Due, vi darà un ulteriore due richieste simultanee per recuperare le immagini.

Avete preso in considerazione la creazione di un HttpHandler per servire le vostre immagini?

attributo

SessionState è molto utile se u utilizzare MVC3. Come raggiungere questo obiettivo con MVC2 ha bisogno di un po 'più di codifica.

L'idea è di raccontare l'asp.net che specifica richiesta solito usa oggetto di sessione.

Quindi, Creare un gestore rotta personalizzata per specifiche richieste

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 ha 4 membri, si dovrebbe usare "disabilità" o "sola lettura" modalità per ottenere un comportamento asincrona.

Dopo aver creato questo gestore itinerario personalizzato, essere sicuri che le vostre richieste specifiche passa attraverso questo gestore. Questo può essere fatto tramite nuove rotte definendo Global.asax

routes.Add("Default", new Route(
                "{controller}/{action}",
               new RouteValueDictionary(new { controller = "Home", action = "Index"}),
               new CustomRouteHandler()
                ));

L'aggiunta di questo percorso rende tutte le vostre richieste per essere gestite dalla vostra abitudine classe del gestore percorso. Si può rendere specifico definendo percorsi diversi.

Cambia DefaultCOntrollerFactory alla classe ControllerFactory personalizzata. Controller.TempDataProvider predefinito usa SessionStateTempDataProvider. si può cambiare.

1.Set web.config / system.web / sessionState:. Mode = "Off"

2.Creare DictionaryTempDataProvider classe.

  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.Create DictionaryTempDataControllerFactory

  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.In global.asax.cs Apprication_Start evento impostato DictionaryTempDataControllerFactory.

protected void Application_Start()
{
  RegisterRoutes(RouteTable.Routes);

  ControllerBuilder.Current.SetControllerFactory(
   new DictionaryTempDataControllerFactory()
  );
}

Il nostro server, IIS non sa nemmeno sulle sessioni - è lo stack ASP.NET gestisce una richiesta che per ogni sessione alla volta. file statici, come le immagini, non vengono mai colpiti.

E 'possibile che la vostra applicazione ASP.NET è servire i file invece di IIS?

Crea nuovo controller

Decorare con controler [SessionState (SessionStateBehavior.Disabled)]

Codice Refactor desideri seesion dichiarato disabilitata per a tale controller

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top