如何在ASP.NET MVC 4应用程序中使用会话?

Thu*_*gwe 104 asp.net-mvc session session-variables asp.net-mvc-4

我是ASP.NET MVC的新手.我之前使用过PHP,很容易创建会话并根据当前会话变量选择用户记录.

我在互联网上到处寻找一个简单的分步教程,可以向我展示如何在我的C#ASP.NET MVC 4应用程序中创建和使用会话.我想创建一个包含用户变量的会话,我可以从我的控制器中的任何位置访问它,并且能够在我的LINQ查询中使用变量.

-提前致谢!

Job*_*mno 153

尝试

//adding data to session
//assuming the method below will return list of Products

var products=Db.GetProducts();

//Store the products to a session

Session["products"]=products;

//To get what you have stored to a session

var products=Session["products"] as List<Product>;

//to clear the session value

Session["products"]=null;
Run Code Online (Sandbox Code Playgroud)

  • 您可以在会话中存储任何类型的任何内容或任何数据.创建后,您可以访问所有视图和控制器中存储的值.请注意,创建的会话只能按用户和每个浏览器访问.这意味着User1使用Firefox创建的会话不能由使用IE的同一用户访问.还有一些你不应该做的事情,如.不要在其上存储大量数据.这可能会降低服务器的性能.最后,请勿将敏感数据存储到会话中,例如密码或信用卡号 (30认同)
  • 谢谢Jobert!你给了我一个主意!只是想知道..,可以在登录期间将用户变量添加到会话中吗?我还可以访问应用程序中不同控制器的会话变量(仅创建一次)吗? (3认同)
  • 再次感谢!我在哪里创建它以便能够跨不同的控制器访问它? (2认同)
  • @JobertEnamno是否可以安全地存储来自`WebSecurity.CurrentUserId`的值,因此它不会多次从数据库中提取它(我发现它非常昂贵)? (2认同)
  • 没有跨控制器会话,因此当您请求另一个控制器时,例如从 `Account/LogOn` 到 `Home/Index`,`Session["FirstName"]` 为 `null`。开发人员必须创建一个父控制器(`BaseController`)并定义一个受保护的字段(`internal protected HttpSessionStateBase SharedSession`),该字段可能会在所有子控制器中公开共享会话变量(假设您的所有应用程序控制器都继承自“BaseController” ) (2认同)

Jos*_*ard 61

由于Web的无状态特性,会话也是一种非常有用的方法,可以通过将对象序列化并将它们存储在会话中来跨对请求来保持对象.

一个完美的用例可能是,如果您需要访问整个应用程序的常规信息,为每个请求保存额外的数据库调用,这些数据可以存储在一个对象中并在每个请求上反序列化,如下所示:

我们可重用,可序列化的对象:

[Serializable]
public class UserProfileSessionData
{
    public int UserId { get; set; }

    public string EmailAddress { get; set; }

    public string FullName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

使用案例:

public class LoginController : Controller {

    [HttpPost]
    public ActionResult Login(LoginModel model)
    {
        if (ModelState.IsValid)
        {
            var profileData = new UserProfileSessionData {
                UserId = model.UserId,
                EmailAddress = model.EmailAddress,
                FullName = model.FullName
            }

            this.Session["UserProfile"] = profileData;
        }
    }

    public ActionResult LoggedInStatusMessage()
    {
        var profileData = this.Session["UserProfile"] as UserProfileSessionData;

        /* From here you could output profileData.FullName to a view and
        save yourself unnecessary database calls */
    }

}
Run Code Online (Sandbox Code Playgroud)

一旦该对象被序列化,我们就可以在所有控制器中使用它,而无需创建它或再次查询数据库中包含的数据.

使用依赖注入注入会话对象

在一个理想的世界中,你将" 编程到一个接口,而不是实现 ",并使用你选择的Inversion of Control容器将可序列化的会话对象注入你的控制器,就像这样(这个例子使用StructureMap,因为它是我最熟悉的那个) ).

public class WebsiteRegistry : Registry
{
    public WebsiteRegistry()
    {
        this.For<IUserProfileSessionData>().HybridHttpOrThreadLocalScoped().Use(() => GetUserProfileFromSession());   
    }

    public static IUserProfileSessionData GetUserProfileFromSession()
    {
        var session = HttpContext.Current.Session;
        if (session["UserProfile"] != null)
        {
            return session["UserProfile"] as IUserProfileSessionData;
        }

        /* Create new empty session object */
        session["UserProfile"] = new UserProfileSessionData();

        return session["UserProfile"] as IUserProfileSessionData;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在您的Global.asax.cs文件中注册.

对于那些不熟悉注入会话对象的人,您可以在此处找到有关该主题的更深入的博客文章.

一句警告:

值得注意的是,会话应该保持在最低限度,大型会话可能会导致性能问题.

还建议不要在其中存储任何敏感数据(密码等).


Len*_*rri 17

这是会话状态在ASP.NET和ASP.NET MVC中的工作方式:

ASP.NET会话状态概述

基本上,这样做是为了在Session对象中存储一个值:

Session["FirstName"] = FirstNameTextBox.Text;
Run Code Online (Sandbox Code Playgroud)

要检索值:

var firstName = Session["FirstName"];
Run Code Online (Sandbox Code Playgroud)

  • 没有交叉控制器会话,因此当您请求另一个控制器时,例如从"Account"到"Home",Session ["FirstName"]为空.开发人员必须创建一个`BaseController`并定义一个受保护的字段(`internal protected HttpSessionStateBase SharedSession`),它可以在所有子控制器中公开共享的`Session`变量(假设你的所有app控制器都继承自`BaseController`) (10认同)
  • @Bellash这是完全错误的.控制器可以使用各种控制器我只需在HomeController中设置Session ["test"],然后在我的AccountController中读取它. (6认同)
  • 嗯,确定有吗?Controller(MVC提供的基本控制器)中有一个Session变量。 (3认同)