我选择进行会话以存储我需要在少数控制器和视图中调用和更新的值。我知道使用BaseViewModel.cs可以做类似的事情,或者更少 session-y ,但我试图看看Session如何能够解决我的需求。这就是我正在做的事情:
我的部分视图在我的_layout页面上呈现,如下所示:
@Html.Action("OrgSwitch", new { controller = "Common", area = "InkScroll" })
这是一个包含已登录用户组织的下拉列表。它命中一个CommonController,负责处理在布局页面上渲染模型绑定逻辑的事情。在CommonController中,我有这个视图和回发,如下所示:
[ChildActionOnly]
public ViewResult OrgSwitch()
{
var userOrgs = new List<SelectListItem>();
var user = Ctx.Users.FirstOrDefault(x => x.UserName == User.Identity.Name);
int key = 0;
if (user.Organizations.Count > 0)
{
TempData["HasOrgs"] = true;
foreach (var org in user.Organizations)
{
if (Session["SelectedOrgKey"] == null)
{
//currently setting selected by primary org id
//todo: set selected to tempdata selectedOrgId if there is one.
userOrgs.Add(org.OrganizationId.ToString() == user.PrimaryOrgId
? new SelectListItem { Text = org.Name, Value = org.OrganizationId.ToString(), Selected = true }
: new SelectListItem { Text = org.Name, Value = org.OrganizationId.ToString(), Selected = false });
}
else
{
key = Convert.ToInt32(Session["SelectedOrgKey"]);
userOrgs.Add(org.OrganizationId == key
? new SelectListItem { Text = org.Name, Value = org.OrganizationId.ToString(), Selected = true }
: new SelectListItem { Text = org.Name, Value = org.OrganizationId.ToString(), Selected = false });
}
}
ViewBag.UserOrgs = userOrgs.OrderBy(x => x.Text);
}
else
{
ViewBag.UserOrgs = userOrgs;
TempData["HasOrgs"] = false;
}
Session["SelectedOrgKey"] = key;
return View();
}
[HttpPost]
public RedirectToRouteResult OrgSwitch(string UserOrgs)
{
Session["SelectedOrgKey"] = UserOrgs;
return RedirectToAction("Index", "Recruiter", new { orgId = UserOrgs, area = "InkScroll" });
}
这种或多或少的初始加载将呈现下拉列表并将其默认为用户主要组织。如果他们选择了某些内容并回发了该选项,则默认情况下会在后续页面上显示所选内容。
我正在尝试各种方式来利用Session值。视图中的一个区域:
[ChildActionOnly]
public ViewResult StaffList()
{
var user = Ctx.Users.FirstOrDefault(x => x.UserName == User.Identity.Name);
var model = new List<StaffListViewModel>();
int key = Convert.ToInt32(Session["SelectedOrgKey"]);
var org = user.Organizations.FirstOrDefault(x => x.OrganizationId == key);
if (org.RegisteredMembers != null)
{
foreach (var req in org.RegisteredMembers)
{
model.Add(new StaffListViewModel
{
UserName = req.UserName,
Name = (req.FirstName ?? "") + " " + (req.LastName ?? ""),
ImageLocation = req.ImageLocation
});
}
}
Session["SelectedOrgKey"] = key;
return View(model);
}
在这里'key'即将出现。
另一个尝试是将它放在布局cshtml文件中,如下所示:
<li><a href="@Url.Action("Staff", "Recruiter", new {area="",
orgId = Convert.ToInt32(Session["SelectedOrgId"])})">Staff</a></li>
在这一个中如果我将鼠标悬停在链接上,则orgId总是等于0.我是否在某处弄乱了?真的,我需要将这个SelectedOrgId用于应用程序的任何页面。
答案 0 :(得分:5)
后人的答案:
问题中的代码可行。我在asp.net mvc中设置和调用会话的方式很好。如果你来到这里是徒劳的搜索以使会话工作,那么继续看我猜。我遇到的问题与我的控制流和我传入的参数有关。一旦我从上面的参数中删除了'orgId',我重构了if / else的东西,只看会话。所以问题是我正在处理的app中的某个地方,orgId没有从'0'改变。无论如何,我是一个白痴,但至少我可以快速概述一下asp.net mvc中的会话是什么以及使用起来有多容易:
会话默认为超时20分钟。如果您觉得有什么东西会覆盖默认值,您可以在web.config中明确设置它(在标准的asp.net mvc应用程序上的root web.config):
<system.web>
<sessionState mode="InProc" timeout="60"></sessionState>
...other stuff..
</system.web>
我将timeout
上面设置为60分钟,因为我希望它能保持更长时间。标准是20。
非常简单。这样做:
Session["MyStringVariable"] = "Some value I want to keep around";
Session["MyIntegerVariable"] = 42;
再次,非常简单,你只需要注意将变量转换/转换为适合你的变量。
var localVar = Session["MyStringVariable"].ToString();
var anotherLocalVar = Convert.ToInt32(Session["MyIntegerVariable"] = 42);
所以,是的,我做得对,但由于我上面的代码中的其他复杂性,我指责了重要的会议,而不是我的大脑。
希望这有助于某人! (如果我的上述信息有误,请告诉我,我会更新!)。