led*_*per 7 c# asp.net asp.net-mvc session asp.net-mvc-4
我选择进行会话来存储一个值,我需要在少数控制器和视图中调用和更新.我知道可以使用BaseViewModel.cs或者更少的session-y来做类似的事情,但我试图看看Session如何能够解决我的需求.这就是我正在做的事情:
我有一个局部视图,在我的_layout页面上呈现如下:
@Html.Action("OrgSwitch", new { controller = "Common", area = "InkScroll" })
Run Code Online (Sandbox Code Playgroud)
这是一个包含登录用户组织的下拉列表.它命中一个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" });
}
Run Code Online (Sandbox Code Playgroud)
初始加载时或多或少会呈现下拉列表,并将其默认为用户主要组织.如果他们选择了某些内容并回发了该选项,则默认情况下会在后续页面上显示所选内容.
我正在尝试各种方式来利用Session值.viewresult中的一个区域:
[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);
}
Run Code Online (Sandbox Code Playgroud)
在这里'钥匙'是空的.
另一个尝试是将它放在布局cshtml文件中,如下所示:
<li><a href="@Url.Action("Staff", "Recruiter", new {area="",
orgId = Convert.ToInt32(Session["SelectedOrgId"])})">Staff</a></li>
Run Code Online (Sandbox Code Playgroud)
在这一个中,如果我将鼠标悬停在链接上,则orgId总是等于0.我是否在某处弄乱了?真的,我需要将这个SelectedOrgId用于应用程序的任何页面.
后人的答案:
问题中的代码是否有效.我在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>
Run Code Online (Sandbox Code Playgroud)
我将timeout上面的时间设置为60分钟,因为我希望它能够保持一段时间.标准是20.
非常简单.做这个:
Session["MyStringVariable"] = "Some value I want to keep around";
Session["MyIntegerVariable"] = 42;
Run Code Online (Sandbox Code Playgroud)
再一次,非常简单,你只需要注意将变量转换/转换为适合你的变量.
var localVar = Session["MyStringVariable"].ToString();
var anotherLocalVar = Convert.ToInt32(Session["MyIntegerVariable"] = 42);
Run Code Online (Sandbox Code Playgroud)
所以,是的,我做得对,但由于我上面的代码中的其他复杂性,我指责了重大的不好的会议,而不是我的大脑.
希望这有助于某人!(如果我有上述信息错误,请告诉我,我会更新!).