Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

[SessionState(SessionStateBehavior.ReadOnly)]

Подробнее см. http://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute.aspx.

Благодаря fooobar.com/questions/93061/...

Ответ 3

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

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

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

Ответ 4

Атрибут SessionState весьма полезен, если вы используете mvc3. Как добиться этого с помощью mvc2 требуется немного больше кодирования.

Идея - сообщить asp.net, что конкретный запрос не использует объект сеанса.

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

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 имеет 4 члена, вы должны использовать режимы "disabled" или "readonly" для получения асинхронного поведения.

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

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

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

Ответ 5

Измените DefaultCOntrollerFactory на пользовательский класс ControllerFactory. Default Controller.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.Создать словарьTempDataControllerFactory

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

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

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

Ответ 6

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

  • Создать пользовательский атрибут
  • Переопределить метод GetControllerSessionBehavior, присутствующий в классе DefaultControllerFactory.
  • Зарегистрировать его в global.aspx

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

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

2. Override

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.asax

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

Ответ 7

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

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

Ответ 8

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

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

Код рефакторинга, для которого вы хотите, чтобы показания отключены для этого контроллера.