C#/ASP.NET-在会话中存储通用列表,而不是在会话中存储单个变量
我已经看到许多ASP.NET会话状态的“包装器”类,其中一些类执行以下操作: 强类型层(伪代码#1)C#/ASP.NET-在会话中存储通用列表,而不是在会话中存储单个变量,c#,asp.net,session,model-view-controller,C#,Asp.net,Session,Model View Controller,我已经看到许多ASP.NET会话状态的“包装器”类,其中一些类执行以下操作: 强类型层(伪代码#1) public class MySession { public int MyID { get { return Convert.ToInt32(HttpContext.Current.Session["MyID"]); } set { HttpConte
public class MySession
{
public int MyID
{
get
{
return Convert.ToInt32(HttpContext.Current.Session["MyID"]);
}
set
{
HttpContext.Current.Session["MyID"] = value;
}
}
public string MyName
{
get
{
return (HttpContext.Current.Session["MyName"]).ToString();
}
set
{
HttpContext.Current.Session["MyName"] = value;
}
}
...
public MySession()
{
// Could be static or instantiated depending on needs...
}
...
}
///// USAGE IN OTHER CLASS /////
MySession currSession = new MySession();
currSession.MyID = 5;
currSession.MyName = "John Doe";
Console.WriteLine($"{currSession.MyName}'s ID = {currSession.MyID}");
然后我看到其他人做了类似的事情:
通用列表变量(伪代码#2)
我更喜欢后者(只是看起来更干净),尽管这很容易隐藏在超类中,或者只是让局部变量直接引用列表:
myObject.TheList.VariableIWant
VS
myObject.VariableIWant
new MySession(); // Create the variables
List<SessionVariables> mySession = MySession.Variables;
newmysession();//创建变量
列出mySession=mySession.Variables;
。。。虽然乍一看那有点脏。然而,我不知道使用列表存储实际上给代码/性能带来了多大好处,因为存储表示列表的对象应该与单独处理每个变量占用同样多的内存,至少这是我的想法
问题
从长远来看,哪种做法更好/维护成本更低?和/或哪个网站性能更好?选项1是我看到的最常见的模式,我使用它。您可以通过使用常量而不是神奇的字符串来改进它。会话有它们的问题,但是制作一个完全无状态的应用程序也是如此。我还建议使用HttpCache而不是Session——它不会消耗AppPool资源。但是,只要使用SQL Server之类的会话提供程序,web场上只能使用会话。分布式缓存是另一回事。使用选项1,很容易判断它在做什么。您正在尝试标准化类如何保存/检索会话数据,而不是将其分散在各个地方 选项2更令人困惑。事实上,我已经看了好几遍了,我不知道清单上是怎么回事。为什么选项2需要列表而选项1不需要 对于您试图做的事情,选项1很好。常数不是个坏主意,但在这种情况下,我可能会跳过它。字符串的含义非常明显,其他类不需要复制它,因为它们通过这个字符串访问会话 选项1>选项2 原因有二:
列表)。这会产生歧义:如果会话存储在proc中,那么会话只存储一个指针,您可以像普通引用类型一样。但是,如果您的会话处于进程外(例如,使用状态服务器或SQL状态),那么您的对象将被序列化和冻结,并且如果您更改引用的对象,这些更改将不会反映在会话变量中。这可能会产生各种只出现在上层环境中的bug(如果您的开发系统缺少状态服务器的话),并让您疯狂地尝试故障排除
您可能会对不可变的引用类型做一个例外,但您必须小心;对象不可变并不意味着它引用的对象也不可变
会议是邪恶的。最好的方法是不要使用会话和构建无状态网站。这两种解决方案看起来不是线程安全的,而且我认为它们也不能很好地工作。@FilipCord也是,是的(因此使用一个自定义类来包装它)…但有时您必须使用会话/自定义包装类。使用查询字符串可能(有时)被认为是一种安全风险,因为您将有关服务器代码的知识公开给最终用户,这很少是一个好主意。那么,您如何将特定信息从一页传输到下一页?i、 例如,如果用户单击订单,您如何将订单号转移到订单详细信息页面?
new MySession(); // Create the variables
List<SessionVariables> mySession = MySession.Variables;