Як можна відключити стан сеансу в ASP.NET MVC?


77

Я хотів би мати дуже легкий сайт ASP.NET MVC, який включає видалення якомога більшої кількості звичних модулів HttpModules та вимкнення стану сеансу. Однак, коли я намагаюся зробити це, я отримую таку помилку:

The SessionStateTempDataProvider requires SessionState to be enabled.

Я вимкнув стан сеансу в web.config:

<sessionState mode="Off" />

Я розумію, що ASP.NET MVC використовує стан сеансу для TempData, але мені не потрібні / потрібні TempData - я просто хочу відключити стан сеансу. Допоможіть!


Приємна ідея - мені було б цікаво почути, якщо у вас виникли якісь інші проблеми з цим, і наскільки легким ви змогли отримати в підсумку.
Майкл Харт,

Я не робив набагато більше експериментів після того, як впровадив зміни Стіва, але все-таки було немало накладних витрат. Найшвидше, що мені вдалося запустити ASP.NET, це прямі реалізації IHttpHandler. Дивіться мою відповідь тут для отримання додаткової інформації: stackoverflow.com/questions/509978/…
Даніель Шаффер

26
Це виправлено в MVC 2. Ми виправили постачальника тимчасових даних стану сеансу, який він не буде видавати, якщо ви насправді не спробуєте прочитати / записати тимчасові дані.
Бред Вілсон,

Бред: Чудово, приємно знати!
Даніель Шаффер

Відповіді:


48

Ви можете створити власні ControllerFactory та DummyTempDataProvider. Щось на зразок цього:

public class NoSessionControllerFactory : DefaultControllerFactory
{
  protected override IController GetControllerInstance(Type controllerType)
  {
    var controller = base.GetControllerInstance(controllerType);
    ((Controller) controller).TempDataProvider = new DummyTempDataProvider();
    return controller;
  }
}


public class DummyTempDataProvider : ITempDataProvider
{
  public IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
  {
    return new Dictionary<string, object>();
  }

  public void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
  {
  }
}

І тоді вам просто потрібно буде зареєструвати фабрику контролерів під час запуску програми - наприклад, ви можете зробити це в global.asax:

ControllerBuilder.Current.SetControllerFactory(new NoSessionControllerFactory());

1
Дякую ... все ще не ідеально (принаймні для мене), але все ж краще, ніж робити це на кожному контролері.
Даніель Шаффер

10
Вибачте, це звучало по-справжньому невдячно ... не означало, що так буде: D
Деніел Шаффер

3
хе-хе, немає проблем :) Я розумію, що це може здатися більшим кодом, ніж ви в ідеалі хотіли б, оскільки, здається, це має бути налаштованою річчю, але однією з найбільших сильних сторін ASP.NET MVC є такий тип конфігурації через надання альтернативних варіантів реалізації за допомогою коду. Це дає вам багато сил, щоб увійти туди і робити речі так, як ви хочете, і загалом я б сказав, що це справді "гарна річ". Особисто я все одно віддаю перевагу коду C #, ніж xml;)
Стів Віллкок,

Привіт Стіве. Я щойно реалізував ваш код у своєму proj. Це добре працює. Дякую! Зараз у мене відключена сесія.
Кирило Гупта,

4
Я додав ще один фрагмент до свого рішення в методі SaveTempData: if (values.Count! = 0) викинути новий NotImplementedException ("Не вдається встановити tempdata, стан сеансу недоступний"); tinyurl.com/mbegfr
BillRob

9

Я знайшов один спосіб, до якого я особливо не дбаю:

Створіть NoTempDataProvider

using System;
using System.Collections.Generic;
using System.Web.Mvc;

namespace Facebook.Sites.Desktop.Auth.Models
{
    public class NoTempDataProvider : ITempDataProvider
    {
        #region [ ITempDataProvider Members ]

        public IDictionary<String, Object> LoadTempData(ControllerContext controllerContext)
        {
            return new Dictionary<String, Object>();
        }

        public void SaveTempData(ControllerContext controllerContext, IDictionary<String, Object> values) { }

        #endregion
    }
}

Запишіть постачальника вручну в контролері

public class AuthController : Controller
{
    public AuthController()
    {
        this.TempDataProvider = new NoTempDataProvider();
    }
}

Я дуже хотів би зробити це повністю за допомогою конфігурації, але це працює наразі.


4
Так, ваш спосіб подібний до того, як я зазначив у своїй відповіді, хоча вам не потрібно вручну перевизначати TempDataProvider у кожному контролері, якщо ви надаєте власний ControllerFactory, який обробляє його для вас.
Steve Willcock

5
Ви також можете створити базовий клас Controller і налаштувати TempDataProvider у його конструкторі.
Бреннон,



0

Сучасне рішення:

Якщо в ASP.NET ви не використовуєте об'єкт Session для зберігання будь-яких даних або якщо обробляється будь-яка з подій Session (Session_OnStart або Session_OnEnd), стан сеансу вимкнено.

Тому, не використовуючи Session (або TempData), відключає стан Session.

Джерело

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.