在您的示例中,您在会话中放置的不是动态对象,而是匿名类的实例。然而,这不起作用,因为为了在从会话中读取对象时访问对象的属性,您必须将其转换为正确的类型,在本例中为匿名类。由于您不知道匿名类的名称(这就是它是匿名的原因),因此您不能执行此转换。
解决方法有以下三种:
- 使用命名类
- 使用字典
- 使用动态对象
1。使用命名类
这个真的很简单,只需要创建一个类(或结构体)就可以了:
public class UserData {
public string UserName {get; set;}
public string Email {get; set;}
public string UserType {get; set;}
}
然后使用该类的实例将数据存储在会话中:
Session["User"] = new UserData {UserName = "abc", Email= "a@a.com", UserType="User"};
并像这样访问它:
var user = (UserData)Session["User"];
var userName = user.UserName;
在这种情况下,您失去了“活力”,因为您必须预先声明所有属性,但您会得到一些编译时间检查作为回报,这是一件好事。除非有很好的理由存储动态值,否则我会选择这个解决方案。
2。使用字典
在这里,您在会话中存储Dictionary<string, string>:
Session["User"] = new Dictionary<string, string> {{"UserName", "abc"}, {"Email", "a@a.com"}, {"UserType", "User"} };
并访问它:
var userDict = (Dictionary<string, string>)Session["User"];
var userName = userDict["UserName"];
3。使用动态对象
这与使用字典没有什么不同,因为它不提供编译时类型检查,但提供了更好的语法。
dynamic userData = new ExpandoObject();
userData.UserName = "abc";
userData.Email = "a@a.com";
userData.UserType = "User";
Session["User"] = userData;
或者,正如@James 在评论中指出的那样,您也可以在此处使用匿名类型,就像您在原始示例中使用的那样:
Session["User"] = new {UserName="abc", Email="a@a.com", UserType="User"};
并访问它:
dynamic userData = Session["User"];
var userName = userData.UserName;