Отключить состояние сеанса на запрос в ASP.Net в MVC

Я создаю ActionResult в ASP.Net MVC для обслуживания изображений. С сеанса IIS будет обрабатывать только один запрос за раз от одного пользователя. (Это верно не только в MVC.)

таким образом, на странице с несколькими изображениями, вызывающими это действие, одновременно может быть обработан только один запрос изображения. Это синхронно.

Я хотел бы, чтобы это действие изображения было асинхронным - я хотел бы, чтобы несколько запросов изображения для каждого выполнялись без необходимости предыдущего один для завершения. (Если бы изображения были просто статическими файлами, IIS обслуживал бы их таким образом.)

Итак, я хотел бы отключить сеанс только для вызовов этого действия или указать, что некоторые запросы не имеют состояния сеанса. Кто знает, как это делается в MVC? Спасибо!

8 ответов


вместо реализации фильтра действий для этого, почему бы вам не реализовать RouteHandler?

вот такие IRouteHandler есть один способ - GetHttpHandler. Когда вы делаете ASP.Net запрос MVC к контроллеру, по умолчанию механизм маршрутизации обрабатывает запрос, создавая новый экземпляр MvcRouteHandler, который возвращает MvcHandler. MvcHandler реализация IHttpHandler который отмечен (сюрприз!) IRequiresSessionState интерфейс. Вот почему обычный запрос использует Сессия.

если вы следите за моим сообщением в блоге о том, как реализовать пользовательский RouteHandler (вместо использования MvcRouteHandler) для обслуживания изображений - вы можете пропустить возврат сеанса с тегом IHttpHandler.

это должно освободить IIS от навязывания вам синхронности. Он также, вероятно, будет более эффективным, потому что он пропускает все слои кода MVC, связанные с фильтрами.


Если кто-то находится в ситуации, в которой я был, где ваш контроллер изображений фактически нуждается в доступе только для чтения к сеансу, вы можете поместить атрибут SessionState на свой контроллер

[SessionState(SessionStateBehavior.ReadOnly)]

см.http://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute.aspx для получения дополнительной информации.

спасибо https://stackoverflow.com/a/4235006/372926


попробуйте обслуживать изображения из другого домена. Что-то вроде images.mysite.com.

Это предоставит вам два преимущества: Во-первых, сеансы отслеживаются файлом cookie, поэтому images.mysite.com не будет печенья. Во-вторых, это даст вам дополнительные два одновременных запроса на получение изображений.

вы рассматривали возможность настройки HttpHandler для обслуживания ваших изображений?


Я также столкнулся с той же проблемой, и после выполнения R&D Эта ссылка работала для меня Ссылка: https://techatfingers.wordpress.com/2016/06/14/session-state-on-action/

  1. создать пользовательский атрибут
  2. переопределить метод "GetControllerSessionBehavior", присутствующий в классе DefaultControllerFactory.
  3. зарегистрируйте его в global.аспн

1> создать пользовательское Атрибут

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

2. Переопределить

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. Зарегистрировать класс В Global.асакс

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

атрибут SessionState весьма полезен, если u использует mvc3. Как достичь этого с mvc2 нужно немного больше кода.

идея сказать asp.net этот конкретный запрос не будет использовать объект session.

Итак, создайте пользовательский обработчик маршрута для определенных запросов

public class CustomRouteHandler : IRouteHandler
    {
        public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            requestContext.HttpContext.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);
            return new MvcHandler(requestContext);
        }
    }

перечисление SessionStateBehavior имеет 4 члена, Вы должны использовать режимы "disabled" или "readonly" для получения асинхронного поведения.

после создания этого пользовательского обработчика маршрута убедитесь, что ваши конкретные запросы проходят через этот обработчик. Это можно сделать путем определения новых маршрутов в Global.асакс

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

добавление этого маршрута делает все ваши запросы обрабатываемыми вашим пользовательским классом обработчика маршрута. Вы можете сделать его конкретным, определив различные маршруты.


измените DefaultCOntrollerFactory на пользовательский класс ControllerFactory. Контроллер По Умолчанию.TempDataProvider используйте SessionStateTempDataProvider. вы можете изменить его.

1.Установить web.config / system.web/sessionState: mode="Off".

2.создайте класс 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.Создать 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.В глобальном.асакс.набор событий cs Apprication_Start DictionaryTempDataControllerFactory.

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

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

на нашем сервере IIS даже не знает о сеансах-это ASP.NET стек, который обрабатывает один запрос на сеанс за раз. Статические файлы, как и изображения, никогда не затрагиваются.

возможно ли, что ваш ASP.NET приложение обслуживает файлы вместо IIS?


создать новый контроллер

украсьте контроллер с помощью [SessionState (SessionStateBehavior.Отключено)]

рефакторинг кода сессии заявил отключена для этого контроллера