登录方式:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login([Bind(Include = "Id,Mail,Pass")] LoginMember member)
{
if (!(ModelState.IsValidField("Mail") && ModelState.IsValidField("Pass")))
{
return View(login);
}
var areThere = db.LoginMember.Any(x => x.Mail == member.Mail && x.Sifre == member.Sifre);
if (areThere)
{
var name = db.LoginMember.Where(x => x.Id == member.Id).Select(x => x.Name);
Session["login"] = name;
return RedirectToAction("Index", "Index");
}
}
此方法正在运行,会话正在创建“Session [”login“] = name;”然后“返回RedirectToAction(”索引“,”索引“);”。
索引视图:
@{
Layout = null;
}
@Session["login"]
<html>Index</html>
当Index视图运行时,出现错误“System.ObjectDisposedException:ObjectContext实例已被释放,不能再用于需要连接的操作。”,有什么问题?
答案 0 :(得分:3)
我相信你的问题就在这里......
var name = db.LoginMember.Where(x => x.Id == member.Id).Select(x => x.Name);
来自Where
和Select
的返回值仍保留对ObjectContext
的引用,请记住这些扩展方法是使用延迟执行实现的,查询在您枚举之前不会执行它。然后,当您将IEnumarable
对象保存到会话变量然后从控制器的操作方法“返回”时,ObjectContext
就会被收集,因为据说它不再需要了。因此,基本上一旦视图引擎呈现索引视图,您的会话变量就会持有一个被处置对象...因此当您尝试访问它时会出现异常。
要解决此问题,您需要“解析”Linq表达式。我建议使用FirstOrDefault
,因为你只期待一个(并且只有一个)用户...
var user = db.LoginMember.FirstOrDefault(x => x.Id == member.Id);
var username = user != null ? user.Name : string.Empty;
以上更安全,您可以保证如果找不到用户FirstOrDefault
将不会抛出异常