如何在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-我只想禁用会话状态。救命!


好主意-如果您遇到其他任何问题以及最终的重量轻,我很想听听。
迈克尔·哈特

在实现了Steve的更改之后,我没有做更多的实验,但是仍然有很多开销。我能够获得ASP.NET最快的就是直接的IHttpHandler实现。见我的答案在这里获得更多信息:stackoverflow.com/questions/509978/...
丹尼尔·谢弗

26
此问题已在MVC 2中修复。我们修复了会话状态临时数据提供程序,除非您实际尝试读写临时数据,否则它将不会抛出该会话状态临时数据提供程序。
布拉德·威尔逊,

布拉德:太好了,很高兴知道!
丹尼尔·谢弗

Answers:


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
Daniel Schaffer

3
呵呵,没问题:)我知道它看起来似乎比您理想的代码要多,因为看起来它应该是可配置的,但是ASP.NET MVC的一大优势就是通过提供替代方法来进行这种类型的配置通过代码实现。它为您提供了强大的力量,可以按照您想要的方式去那里做事,总的来说,我认为这确实是一件“好事”。我个人还是喜欢输入C#代码而不是xml;)
Steve Willcock

嗨,史蒂夫。我刚刚在项目中实现了您的代码。它运作良好。谢谢!现在我禁用了会话。
西里尔·古普塔

4
我在SaveTempData方法的解决方案中又增加了一块:if(values.Count!= 0)throw new NotImplementedException(“无法设置tempdata,没有可用的会话状态”); tinyurl.com/mbegfr
BillRob,2009年

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
是的,您的方式类似于我在答案中概述的方式-尽管如果您提供了一个自定义ControllerFactory来为您处理它,则不必在每个控制器中手动覆盖TempDataProvider。
史蒂夫·威尔科克

5
您还可以创建一个基础Controller类,并在其构造函数中配置TempDataProvider。
布兰农



0

现代解决方案:

在ASP.NET中,如果不使用Session对象存储任何数据,或者如果处理了任何Session事件(Session_OnStart或Session_OnEnd),则将禁用会话状态。

因此,不使用会话(或TempData),则会禁用会话状态。

资源

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.