2008-10-20 2 views
41

Без маршрутизации HttpContext.Current.Session есть, поэтому я знаю, что работает StateServer. Когда я направляю свои запросы, HttpContext.Current.Session - это null на маршрутной странице. Я использую .NET 3.5 sp1 на IIS 7.0 без предварительных просмотров MVC. Похоже, что AcquireRequestState никогда не запускается при использовании маршрутов, поэтому переменная сеанса не создается и не заполняется.HttpContext.Current.Session имеет значение null при запросах маршрутизации

При попытке доступа к переменному сеансу, я получаю эту ошибку:

base {System.Runtime.InteropServices.ExternalException} = {"Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive. Please also make sure that System.Web.SessionStateModule or a custom session state module is included in the <configuration>.

Во время отладки, я получаю сообщение об ошибке, что HttpContext.Current.Session не доступна в этом контексте.

-

Мой web.config выглядит следующим образом:

<configuration> 
    ... 
    <system.web> 
    <pages enableSessionState="true"> 
     <controls> 
     ... 
     </controls> 
    </pages> 
    ... 
    </system.web> 
    <sessionState cookieless="AutoDetect" mode="StateServer" timeout="22" /> 
    ... 
</configuration> 

Вот реализация IRouteHandler:

public class WebPageRouteHandler : IRouteHandler, IRequiresSessionState 
{ 
    public string m_VirtualPath { get; private set; } 
    public bool m_CheckPhysicalUrlAccess { get; set; } 

    public WebPageRouteHandler(string virtualPath) : this(virtualPath, false) 
    { 
    } 
    public WebPageRouteHandler(string virtualPath, bool checkPhysicalUrlAccess) 
    { 
     m_VirtualPath = virtualPath; 
     m_CheckPhysicalUrlAccess = checkPhysicalUrlAccess; 
    } 

    public IHttpHandler GetHttpHandler(RequestContext requestContext) 
    { 
     if (m_CheckPhysicalUrlAccess 
      && !UrlAuthorizationModule.CheckUrlAccessForPrincipal(
        m_VirtualPath, 
        requestContext.HttpContext.User, 
        requestContext.HttpContext.Request.HttpMethod)) 
     { 
      throw new SecurityException(); 
     } 

     string var = String.Empty; 
     foreach (var value in requestContext.RouteData.Values) 
     { 
      requestContext.HttpContext.Items[value.Key] = value.Value; 
     } 

     Page page = BuildManager.CreateInstanceFromVirtualPath(
         m_VirtualPath, 
         typeof(Page)) as Page;// IHttpHandler; 

     if (page != null) 
     { 
      return page; 
     } 
     return page; 
    } 
} 

Я также попытался поставить EnableSessionState="True" на верхней части страницы ASPX но все равно ничего.

Любые идеи? Должен ли я написать еще HttpRequestHandler, который реализует IRequiresSessionState?

Спасибо.

ответ

52

Got it. На самом деле это довольно глупо. Он работал после того, как я удалил & добавил SessionStateModule так:

<configuration> 
    ... 
    <system.webServer> 
    ... 
    <modules> 
     <remove name="Session" /> 
     <add name="Session" type="System.Web.SessionState.SessionStateModule"/> 
     ... 
    </modules> 
    </system.webServer> 
</configuration> 

Просто добавив, что не будет работать, так как «Session» уже должны были быть определены в machine.config.

Теперь, интересно, это обычная вещь. Это, конечно, не кажется так, потому что кажется таким грубым ...

+3

Спасибо за это. Это решило мою проблему красиво - как оказалось, для этого нужен сервер производства, а не dev-машина. – Raithlin 2010-02-03 07:42:04

+2

Это ins @ ne! Благодарю. Это также фиксировало мои значения «TempData» (mvc бритвы) от исчезновения (поскольку TempData использует Session). Святой Моли. – granadaCoder 2015-08-10 20:44:52

+0

У меня проблема с исчезновением значений TempData, но это не решило проблему. – Dinei 2015-08-27 19:54:12

0

Похоже, вы забыли добавить свой государственный серверный адрес в файл config.

<sessionstate mode="StateServer" timeout="20" server="127.0.0.1" port="42424" /> 
+1

Пробовали, но все тот же. Не имеет значения w/его значение по умолчанию: «tcpip = loopback: 42424» (http://msdn.microsoft.com/en-us/library/system.web.configuration.sessionstatesection.stateconnectionstring.aspx) Я сомневаюсь, что проблема связана с провайдером сеанса, поскольку он работает без маршрутизации. – Loki 2008-10-20 11:32:00

0

Раздел конфигурации кажется звуковым, поскольку он работает, если доступ к страницам осуществляется нормально. Я пробовал другие предлагаемые варианты, но проблема все еще существует.

Я сомневаюсь, что проблема связана с провайдером сеанса, поскольку он работает без маршрутизации.

2

Что сказал @Bogdan Maxim. Или измените использование InProc, если вы не используете внешний сервер состояния sesssion.

<sessionState mode="InProc" timeout="20" cookieless="AutoDetect" /> 

Посмотрите here для получения дополнительной информации о директиве SessionState.

+0

SessionState работает, если я обычно открываю страницу. Если я использую маршрутизацию, HttpContext.Current.Session имеет значение null. Секция , похоже, работает в конфиге. – Loki 2008-10-20 11:41:26

0

Я думаю, что эта часть кода вносит изменения в контекст.

Page page = BuildManager.CreateInstanceFromVirtualPath(
         m_VirtualPath, 
         typeof(Page)) as Page;// IHttpHandler; 

Кроме того, эта часть кода бесполезно:

if (page != null) 
{ 
    return page; 
} 
return page; 

Он всегда будет возвращаться страница засыхают это нуль или нет.

+0

Спасибо, что напомнили мне. Это был некоторый рудиментарный код после того, как он опробовал так много вещей. : D – Loki 2008-10-21 09:03:48

3

Хорошая работа! У меня была такая же проблема. Добавление и удаление модуля сеанса отлично работало для меня. Однако он не привел HttpContext.Current.User, поэтому я попробовал ваш небольшой трюк с модулем FormsAuth и, конечно же, сделал это.

<remove name="FormsAuthentication" /> 
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/> 
23

Просто добавьте атрибут runAllManagedModulesForAllRequests="true" к system.webServer\modules в web.config.

Этот атрибут включен по умолчанию в проектах MVC и Dynamic Data.

1

лучшее решение

runAllManagedModulesForAllRequest умный вещь, чтобы сделать уважение и удаление resinserting модуля сеанса.

alk.

14

runAllManagedModulesForAllRequests=true на самом деле настоящее плохое решение. Это увеличило время загрузки моего приложения на 200%. Лучшее решение состоит в том, чтобы вручную удалить и добавить объект сеанса и избежать совпадения всех атрибутов всех управляемых модулей.

0

я пропускал ссылку на DLL System.web.mvc в адаптере сессии, и добавив тот же фиксированный вопрос.

Надеюсь, это поможет кому-то другому пройти через тот же сценарий.

1

Ни один из вышеперечисленных решений не работал для меня. Я добавил следующий метод в global.asax.cs то сессия не была пустой:

protected void Application_PostAuthorizeRequest() 
{ 
    HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required); 
}