当我开始开发Web应用程序时,我将用户的身份验证详细信息存储在两个会话变量中
Session["UserName"]="username";
Session["Password"]="paswword-123";
但有人建议我创建一个包含UserName和Password属性的类,并且在成功身份验证时,我被要求创建该类的实例并设置UserName和Password属性并将该实例存储在会话中。
我被告知会话对象是TypeSafe。有人可以解释什么是类型安全编码以及在会话中存储对象的优势。
答案 0 :(得分:6)
基本上,直接在Session["something"]
中存储值的经典方法有两个缺点:
something
,您的代码编译得很好,但您会遇到运行时错误,或者更糟糕的是,您的代码中会出现一个未被注意的错误。Session["something"]
后,您需要将其投射到您需要的类型。 (这就是“not type-safe”的含义。)使用存储在Session中的强类型对象消除了第二个问题。实际上,你的自定义对象仍然需要被强制转换,但它只有一个强制转换而不是两个(或十个)强制转换,这可以减少出错的可能性。同样,错误的强制转换只能在运行时检测到。
另一种方法是将对Session变量的访问封装在静态属性中:
public class MySession {
public static string UserName {
get { return (string)HttpContext.Current.Session["UserName"]; }
set { HttpContext.Current.Session["UserName"] = value; }
}
}
当然,这两种方法都可以组合在一起,允许您将相关属性(用户名和密码)分组到一个公共对象中。
答案 1 :(得分:3)
拥有一个包含2个字段的User类可能有很多原因,对于类型安全性,如果你在某个地方键入Session [“Pasword”],你会得到一个不容易找到的错误,你将不得不检查两个参数名称。你需要它们是正确的,它是错误的重要来源。一旦您存储User对象而不是2个未连接的字符串,您将能够使用类型安全的代码,如User.Password,而不是尝试通过Session中的字符串索引器访问密码。此外,如果您的用户获得更多字段,这很常见,您只需将它们添加到User类,而不是开始创建新参数&命名并将它们存储在会话堆中。
至于类型安全编码,我认为http://en.wikipedia.org/wiki/Type_safety应该有所帮助,或者我认为非常受欢迎的任何其他类型的文章。
另外我不认为你应该在会话中存储密码,取决于你的程序逻辑,但通常密码只应用于计算其md5哈希值,之后再也不用。
答案 2 :(得分:0)
嗯,你的朋友是对的,但我不相信Session本身就是安全的。 Session集合存储Object的实例。因此,您可以存储任何类型的实例(字符串,int或自定义登录类),因为它们都是从对象派生的。但是,当您检索该对象时,您不知道它是什么类型,并且在使用之前需要使用异常处理小心地将其强制转换。 例如,这很好用:
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)
拥有自定义登录对象可以稍微解决这个问题,因为您只需要担心一个对象,并且需要进行一次转换。您还可以使用额外信息轻松扩展登录对象,而且无需再进行任何演员表。