【问题标题】:ASP.NET session state, serialization, and inheritanceASP.NET 会话状态、序列化和继承
【发布时间】:2011-05-17 16:28:21
【问题描述】:

首先,有一点背景。我有两个使用 SQLServer 会话状态的 ASP.NET Web 应用程序(它们使用相同的服务器,具有相同的凭据)。每个应用程序都定义了一个封装的会话类,它或多或少充当一个容器。

// For example...
public class FirstSession
{
   private string _name;
   public string Name
   {
      get { return this._name; }
      set { this._name = value; }
   }

   public FirstSession()
   {
      this._name = string.Empty;
   }
}

当然,真正的类要复杂得多,但归根结底它主要归结为一种数据结构。每当创建新会话时,应用程序就会使用此类。例如,在 Global.asax 文件中:

protected void Session_Start(object sender, EventArgs e)
{
   // Adds user to session state.
   Session.Add(
      "SK_SessionKey", 
      new FirstSession());
}

我意识到,当使用 SQLServer 会话状态时,给定的类在以这种方式添加对象到会话时必须是可序列化的,但为了简单起见,我省略了这部分。

这两个应用程序中的每一个都定义了自己的一组需要存储在会话中的值,但它们也有大量共同的值(例如,用户 ID 和身份验证标志)。现在,这两个应用程序需要单点登录功能。因此,由于我们使用的是 SQLServer 会话状态,我的想法是使用会话状态本身在两个应用程序之间进行身份验证。

这是我所做的:我创建了第三个程序集,其中包含一个会话类,该类提供将在应用程序之间使用的公共数据值(例如用户 ID 等)。然后我将程序集分发给两个应用程序,这两个应用程序需要向它们的会话对象添加额外的属性。因此,每个应用程序都实现了一个会话类,该会话类派生自外部程序集中包含的基会话类。

我的希望是,由于两个派生类都基于同一个基类(两个应用程序都可以访问),因此,例如,当从第一个应用程序重定向到第二个应用程序时,第二个应用程序可以寻找会话对象,并且在找到第一个应用程序的会话对象后,可以将其转换为基类,提取值,创建并初始化其自己的会话对象,然后将其序列化回会话中。

我尝试使用 ISerializable 来管理与服务器之间的序列化,但仅使用 SerializationInfo 并不能正常工作。我该怎么做呢?我应该序列化为 XML 还是二进制?二进制文件甚至可以与基类/派生类一起使用吗?我应该研究某个框架类吗? (BinaryFormatter?)我使用基类的想法有什么根本错误吗?

=编辑=

我最终使用了 XML 序列化,如 explained here.

【问题讨论】:

    标签: c# asp.net session serialization inheritance


    【解决方案1】:

    会话存储在应用程序存储库的基础上。这两个应用程序都有自己的存储库,它们不知道另一个存在,无论它们是否共享一些代码。

    有几种方法可以实现这一点。有一些产品可以让多个应用程序共享会话状态,但这可能会导致其自身的后勤问题。我不推荐这种方法。

    正确的方法是拥有一个共同的存储库,而不是拥有共同的代码 - 即两个应用程序都有自己的会话,但是两个应用程序都可以使用第三个数据库使用权。 App1 可以使用唯一键将对象写入第三个数据库,通过查询字符串或其他方式将键传递给 App2,然后 App2 可以返回到这个公共数据库并通过相同的键检索数据。

    【讨论】:

    • 我意识到您所描述的方法会更直观,并且实施起来可能更健壮。但是,如果可能的话,我希望能够或多或少地无缝地进行身份验证,而不必在应用程序之间直接传递一些东西(比如查询字符串)。另外,对我来说,更改应用程序比更改数据库要容易得多。而且,实际上,我认为这两个应用程序可以访问同一个会话对象,因为它们使用相同的密钥,并且它们位于同一个域中。只是序列化失败了。
    • @voithos 如果没有重大帮助,他们肯定无法访问同一会话。 ASP.NET SQL 会话提供程序将为每个逻辑应用程序创建一个存储库,而不是每个域或其他任何东西。他们应该能够无缝地进行身份验证 - 从最终用户的角度来看 - 只需检查用户是否经过身份验证,如果没有重定向到其他应用程序,它将放置公共令牌并重定向回来。
    • 事实上,似乎对数据库进行了一些处理以允许这样做,因为它们确实访问不同应用程序之间的相同会话。我知道,这可能不是最好的主意。也许他们做了类似于this blog article中提到的事情?
    • @voithos 听起来很危险。完全有可能构建允许在应用程序之间共享数据的自定义会话状态提供程序,并且有第三方出售。我会避免在 SQL 级别对 Microsoft 的 SQL 会话提供程序的实现进行深入研究。
    【解决方案2】:

    我认为有2个问题:

    • 2 个应用程序可以共享 ASP.Net SQL 会话状态吗? 答案:默认情况下不是 - 包含在 Rex M 的答案中。
    • 如果有 3 个类 SharedASsembly.Base、Assembly1.Derived1:Base、Assembly2.Derived2:Base 是否可以在 Assembly2 中编码反序列化 Derived1 而无需加载 Assembly1? 答案:没有。您将能够在 3 个程序集中的任何一个中反序列化 Base,但要反序列化派生类,您需要加载相应的程序集。

    【讨论】:

    • 所以 Assembly2 不能将 Derived1 视为 Base 吗?
    • 可以,但需要加载 Assembly1,这似乎不是您想要的。
    • 是的...那种破坏了拥有外部程序集的目的。有没有办法改变序列化,从而不必加载 Assembly1?也许是 XML 序列化?
    猜你喜欢
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 2011-09-01
    • 2012-05-07
    相关资源
    最近更新 更多