【问题标题】:strongly typed sessions in asp.netasp.net 中的强类型会话
【发布时间】:2011-01-03 08:33:21
【问题描述】:

如果这个问题已经被问过,请原谅我。 HttpContext.Current.Session["key"] 返回一个对象,我们必须将其转换为特定的 Type 才能使用它。我正在研究类型化会话的各种实现

http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx

如果我们想将新的Type 对象添加到会话中,无论是作为方法还是作为单独的包装器,我觉得我们需要向 SessionManager 添加更多代码(如果我错了,请纠正我)。我认为我们可以使用泛型

public static class SessionManager<T> where T:class
 {
  public void SetSession(string key,object objToStore)
  {
   HttpContext.Current.Session[key] = objToStore;
  }

  public T GetSession(string key)
  {
   return HttpContext.Current.Session[key] as T;
  }

 }
  • 有什么先天优势吗? 使用

    SessionManager&lt;ClassType&gt;.GetSession("sessionString")

比使用

HttpContext.Current.Session["sessionString"] as ClassType
  • 我也觉得会很好 有类似的东西

SessionManager["sessionString"] = objToStoreInSession, 但发现静态类不能有索引器。有没有其他方法可以做到这一点?

  • 我的想法是创建一个 SessionObject 来存储Type 和对象,然后使用密钥将此对象添加到 Session(使用 SessionManager)。检索时,将所有对象转换为SessionObject,获取类型(比如t)和对象(比如obj)并将obj转换为t并返回。

    public class SessionObject { public Type type {get;set;} public Object obj{get;set;}
    }

这也不好用(因为返回签名相同,但返回类型不同)。

是否有任何其他优雅的方式以更安全的方式在会话中保存/检索对象

【问题讨论】:

    标签: asp.net session session-state session-variables


    【解决方案1】:

    要获得一种非常干净、可维护和流畅的 Session 处理方式,请查看post。您会惊讶于它是多么简单。

    【讨论】:

    • 虽然是一篇好文章,但从特定于会话的类派生您的类不会让您从任何其他抽象类/基类派生您的类
    • @Ram 是的,我帖子中课程的重点是它是您希望在会话中存储的任何项目的包装器。我希望你注意到了,这真的再简单不过了。
    • 它真的适用于超出 proc 状态吗?因为会话对象永远不会被写回到会话存储中,所以会话存储中仍然会有之前序列化的旧值。
    • @TheObjectGuy 您答案中的链接似乎已失效。
    【解决方案2】:

    该技术的一个缺点是使用代码需要知道使用什么键来存储和检索。这很容易出错,因为密钥需要完全正确,否则您可能会存储在错误的位置,或者返回空值。

    我实际上使用强类型变体,因为我知道我需要在会话中拥有什么,因此可以设置包装类以适应。我宁愿在会话类中有额外的代码,而不必担心其他任何地方的键字符串。

    【讨论】:

    • 是的,同意你的看法。我看到为会话字符串设置 SessionManager.Constants 作为标准实现以避免拼写错误
    【解决方案3】:

    您可以简单地为会话对象使用单例模式。这样,您可以从单个复合结构对象对整个会话进行建模。这篇文章引用了我正在谈论的内容并将 Session 对象作为弱类型对象进行讨论:http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html

    【讨论】:

      【解决方案4】:

      实际上,如果您要键入对象,请将类型放在方法级别,例如:

      public T GetValue<T>(string sessionKey)
      {
      
      }
      

      如果会话中有相同的对象,则类级别会更高,但会话可以扩展为多种类型。我不知道我会担心控制会话;我只会让它做它所做的一段时间,并简单地提供一种以更强类型的方式提取和保存信息的方法(至少对消费者而言)。

      是的,索引不起作用;您可以将其创建为实例,并通过以下方式使其成为静态:

      public class SessionManager
      {
          private static SessionManager _instance = null;
      
      
          public static SessionManager Create()
          {
             if (_instance != null)
                 return _instance;
      
             //Should use a lock when creating the instance
             //create object for _instance
      
             return _instance;
          }
      
          public object this[string key] { get { .. } }
      }
      

      所以这是静态工厂实现,但它也通过内部对会话管理器类的静态引用来维护单点联系。 sessionmanager 中的每个方法都可以包装现有的 ASP.NET 会话,或者使用您自己的内部存储。

      【讨论】:

        【解决方案5】:

        我在 StackOverflow 问题 is it a good idea to create an enum for the key names of session values? 上发布了解决方案

        我认为它真的很漂亮,并且包含很少的代码来实现它。它需要 .NET 4.5 是最流畅的,但仍然可以使用旧版本。

        它允许:

        int myInt = SessionVars.MyInt; 
        SessionVars.MyInt = 3;
        

        工作完全一样:

        int myInt = (int)Session["MyInt"];
        Session["MyInt"] = 3;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-21
          • 2017-02-12
          • 1970-01-01
          相关资源
          最近更新 更多