题
当我开始开发 Web 应用程序时,我将用户的身份验证详细信息存储在两个会话变量中
Session["UserName"]="username";
Session["Password"]="paswword-123";
但是有人向我提出了一个想法,即创建一个包含用户名和密码属性的类,并且在成功进行身份验证后,我被要求创建该类的实例并设置用户名和密码属性并将该实例存储在会话中。
我被告知会话对象是 TypeSafe。有人可以解释什么是类型安全编码以及将对象存储在会话中的优点吗?
解决方案
基本上,直接将值存储在中的经典方法 Session["something"]
有两个缺点:
- 魔术弦: :如果您输入错误
something
, ,您的代码编译得很好,但您会遇到运行时错误,或者更糟糕的是,代码中出现未被注意到的错误。 - 铸件: :看完之后
Session["something"]
, ,您需要将其转换为您需要的类型。(这就是这个意思 “不是类型安全的”.)
使用存储在会话中的强类型对象消除了第二个问题。好吧,实际上,您的自定义对象仍然需要进行强制转换,但它只是一次强制转换,而不是两次(或十次)强制转换,这减少了出现问题的可能性。同样,错误的强制转换只能在运行时检测到。
另一种方法是将对 Session 变量的访问封装在静态属性中:
public class MySession {
public static string UserName {
get { return (string)HttpContext.Current.Session["UserName"]; }
set { HttpContext.Current.Session["UserName"] = value; }
}
}
当然,这两种方法可以组合使用,从而允许您将相关属性(用户名和密码)分组到一个公共对象中。
其他提示
有2个字段中输入用户类可以有很多原因好,类型安全,如果你曾经类型的会话[“Pasword”]的地方,你会得到不会是那么容易找到一个错误,你将不得不检查到处都参数名称。你需要他们是正确的,其误差的重要来源。一旦你存储用户对象,而不是2个未连接字符串你将能够使用在会话字符串索引类型安全的代码一样user.password的,而不是试图访问密码。此外,如果您的用户不断得到更多的领域,这是很常见的,你会简单地将它们添加到用户类,而不是开始创建新的参数和名称,并将其存储在会话堆。
至于类型安全编码我认为 http://en.wikipedia.org/wiki/Type_safety应该帮助,或主题的任何其他类型的文章,这是非常受欢迎的,我认为。
此外,我不认为你应该存储密码的会议,取决于你的程序逻辑,但通常的密码应只用来计算其MD5哈希值,并永远不会被事后使用。
好你的朋友说对了一半,但我不相信会议本质上是类型安全的。对象的会话集合店的情况。所以,你可以存储任何类型(字符串,一个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)
有一个自定义登录对象稍微解决了这个问题,因为你只能有一个对象来操心,和一个用来铸造。你也可以很容易地与额外的信息扩展登录对象,仍然没有做任何更多的转换。