我想出了一个解决方案,通过保持 Session 变量的结构完整,避免了发布的其他解决方案的某些缺点。它只是获取和设置 Session 变量的类型安全快捷方式。
它是 C#,但我最后发布了一些自动生成的 VB.NET。
我见过的最佳解决方案(接受的答案和 TheObjectGuy 的答案)需要一个自定义类,该类存储在 Session 变量中,然后从 Session 中拉出以使用 MySessionClass.Current.MyProperty 之类的东西访问其属性。
这样做的问题是,如果您当前正在使用(或将来可能使用)InProc 会话状态模式以外的其他东西(请参阅https://msdn.microsoft.com/en-us/library/ms178586%28v= vs.140%29.aspx),整个类都必须通过序列化来访问单个属性。
此外,如果您需要,这意味着您会丢失实际 Session 提供的 IEnumerable 和 ICollection 实现。使用我的解决方案,如果您需要此功能,您可以简单地访问实际的 Session。
您可以轻松使用这些会话变量,并且它们是类型安全的。它可以与 Session["MyProperty"] 之类的语句一起使用,这将允许一次转换现有项目一个引用。所以:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;
变成:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
这是实际的课程。CallerMemberName 需要 .NET 4.5,但即使您使用的是旧版本,您仍然可以通过显式传递 propertyName 来管理它。此外,属性的类型必须可以为空,以使其行为与标准 Session["MyProp"] 调用完全相同,因为未设置
public static class SessionVars
{
private static T Get2<T>([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
if (HttpContext.Current.Session[propertyName] == null)
{
return default(T);
}
return (T)HttpContext.Current.Session[propertyName];
}
private static void Set2<T>(T value, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
HttpContext.Current.Session[propertyName] = value;
}
public static int MyInt { get { return Get2<int>(); } set { Set2<int>(value); } }
public static bool MyBool { get { return Get2<bool>(); } set { Set2<bool>(value); } }
public static string MyString { get { return Get2<string>(); } set { Set2<string>(value); } }
}
我什至写了一个代码片段来方便添加这些属性:
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<Header>
<Title>SessionVars Property</Title>
<Author>kevinpo</Author>
<Shortcut>sv</Shortcut>
<Description>Adds a property for use in a SessionVars class</Description>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<Default>int</Default>
</Literal>
<Literal>
<ID>property</ID>
<Default>PropertyName</Default>
</Literal>
</Declarations>
<Code Language="CSharp">
<![CDATA[public static $type$ $property$ { get { return Get2<$type$>(); } set { Set2<$type$>(value); } }]]>
</Code>
</Snippet>
</CodeSnippet>
我是 C# 人,所以这个 VB.NET 只是由http://converter.telerik.com/自动转换的:
Public NotInheritable Class SessionVars
Private Sub New()
End Sub
Private Shared Function Get2(Of T)(<System.Runtime.CompilerServices.CallerMemberName> Optional propertyName As String = "") As T
If HttpContext.Current.Session(propertyName) Is Nothing Then
Return Nothing
End If
Return DirectCast(HttpContext.Current.Session(propertyName), T)
End Function
Private Shared Sub Set2(Of T)(value As T, <System.Runtime.CompilerServices.CallerMemberName> Optional propertyName As String = "")
HttpContext.Current.Session(propertyName) = value
End Sub
Public Shared Property MyInt() As Integer
Get
Return Get2(Of Integer)()
End Get
Set
Set2(Of Integer)(value)
End Set
End Property
Public Shared Property MyBool() As Boolean
Get
Return Get2(Of Boolean)()
End Get
Set
Set2(Of Boolean)(value)
End Set
End Property
Public Shared Property MyString() As String
Get
Return Get2(Of String)()
End Get
Set
Set2(Of String)(value)
End Set
End Property
End Class
'=======================================================
'Service provided by Telerik (www.telerik.com)
'Conversion powered by NRefactory.
'Twitter: @telerik
'Facebook: facebook.com/telerik
'=======================================================