2

当我开始开发 Web 应用程序时,我将用户的身份验证详细信息存储在两个会话变量中

 Session["UserName"]="username";
 Session["Password"]="paswword-123";

但是有人向我提出了一个想法,即创建一个包含 UserName 和 Password 属性的类,并且在成功的身份验证后,我被要求创建该类的一个实例并设置 UserName 和 Password 属性并将该实例存储在会话中。

我被告知会话对象是 TypeSafe。有人可以解释什么是类型安全编码以及将对象存储在会话中的优点。

4

3 回答 3

6

基本上,直接存储值的经典方法Session["something"]有两个缺点:

  • 魔术字符串:如果你输入错误something,你的代码编译得很好,但是你会得到一个运行时错误,或者更糟糕的是,你的代码中会出现一个未被注意到的错误。
  • Casting:阅读后Session["something"],需要将其转换为您需要的类型。(这就是“非类型安全”的意思。)

使用存储在 Session 中的强类型对象消除了第二个问题。好吧,实际上,您的自定义对象仍然需要进行转换,但它只是一次转换而不是两次(或十次)转换,这减少了出错的可能性。同样,错误的演员表只能在运行时检测到。

另一种方法是将对 Session 变量的访问封装在静态属性中:

public class MySession {
    public static string UserName {
        get { return (string)HttpContext.Current.Session["UserName"]; }
        set { HttpContext.Current.Session["UserName"] = value; }
    }
}

当然,这两种方法可以结合使用,允许您将相关属性(用户名和密码)分组到一个公共对象中。

于 2010-11-24T13:25:49.060 回答
3

拥有一个带有 2 个字段的 User 类可能有很多好处,至于类型安全,如果你曾经在某处输入 Session["Pasword"] ,你会得到一个不容易找到的错误,你必须检查两者无处不在的参数名称。您需要它们是正确的,这是错误的重要来源。一旦您存储用户对象而不是 2 个未连接的字符串,您将能够使用类型安全代码(如 User.Password),而不是尝试通过会话中的字符串索引器访问密码。此外,如果您的用户获得更多字段,这很常见,您只需将它们添加到 User 类,而不是开始创建新参数和名称并将它们存储在会话堆中。

至于类型安全编码,我认为http://en.wikipedia.org/wiki/Type_safety应该有所帮助,或者我认为非常流行的任何其他类型的主题文章。

此外,我认为您不应该在会话中存储密码,这取决于您的程序逻辑,但通常密码只能用于计算其 md5 哈希值,之后永远不要使用。

于 2010-11-24T13:18:15.413 回答
0

好吧,你的朋友说对了一半,但我不相信 Session 本质上是类型安全的。Session 集合存储 Object 的实例。因此,您可以存储任何类型的实例(字符串、int 或自定义登录类),因为它们都派生自 object。但是,当您检索该对象时,您不知道它是什么类型,并且需要在使用它之前仔细地转换它,并进行异常处理。例如,这很好用:

Session["UserName"] = "Freddy";
string theUserName = (string)Session["UserName"];

但是,您可以尝试执行以下操作,这将导致错误。

Session["UserName"] new StrangeDataClass(); //Uh Oh, that's not a string.
string theUserName = (string)Session["UserName"]; //unexpected behaviour based on StrangeDataClass.ToString() implementation.

要解决此问题,您必须执行以下操作:

string theUserName = Session["UserName"] as string;
if (string != null)
    //The cast worked...
else
    //The cast failed, (or the string stored in session was null)

拥有一个自定义登录对象稍微解决了这个问题,因为您只需要担心一个对象和一个演员表。您还可以使用额外的信息轻松扩展登录对象,并且仍然不必再进行任何强制转换。

于 2010-11-24T13:18:59.167 回答