如何在 ASP 中始终保持会话变量更新。网络MVC
How to keep session variables updated always in ASP. NET MVC
登录后,我在 Session[""]
变量中保留了一些用户信息。
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
try
{
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
var user = User.Identity;
try
{
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
string userId = UserManager.FindByName(model.UserName)?.Id;
var s = UserManager.GetRoles(userId);
var u = db.UsersViews.First(x => x.Id == userId);
Session["UserFullName"] = u.LastName + " " + u.FirstName.Substring(0, 1) + ". " + u.MiddleName.Substring(0, 1) + ".";
Session["UserRole"] = u.RoleName;
return RedirectToAction("Index", "Home");
}
catch (Exception ex)
{
return View("Lockout");
}
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
catch (Exception ex)
{
throw;
}
}
后来我用的像
@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<div class="form-inline my-2 my-lg-0 " style="margin-left:2em; margin-right:0em;">
<label class="form-control-sm mr-sm-2">@Session["UserFullName"] (@Session["UserRole"]) </label>
<a href="javascript:document.getElementById('logoutForm').submit()" class="btn btn-outline-primary btn-sm my-2 my-sm-0">Выход</a>
</div>
}
}
else
{
<form class="navbar-right">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a id="loginLink" href="@Url.Content("~/Account/Login")" class="nav-link"><span class="glyphicon glyphicon-log-in"></span> Вход</a>
</li>
</ul>
</form>
}
但是一旦会话结束,就没有任何值可以显示了。
所以我的问题是如何在不增加会话超时的情况下保持更新的会话变量?
谢谢!
我在这里找到了答案ASP.NET MVC - Set custom IIdentity or IPrincipal
但是我稍微调整了这个方法。
这是我的工作代码。
创建几个 类 of IPrincipal
interface ICustomPrincipal : IPrincipal
{
string Id { get; set; }
string FirstName { get; set; }
string LastName { get; set; }
string MiddleName { get; set; }
string RoleName { get; set; }
}
public class CustomPrincipal : ICustomPrincipal
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string RoleName { get; set; }
private string[] _roles; // Keep here English name of roles that ypu will use for Controller [Authorize(Roles = "Administrator, Guest")]
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
return Array.BinarySearch(_roles, role) >= 0 ? true : false;
}
public CustomPrincipal(IIdentity identity, string[] roles)
{
Identity = identity;
_roles = new string[roles.Length];
roles.CopyTo(_roles, 0);
Array.Sort(_roles);
}
}
public class CustomPrincipalSerializeModel
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string RoleName { get; set; }
public string RoleNameCode { get; set; } // English name of role like 'Administrator'
}
在Global.asax中添加
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// Add this
PostAuthenticateRequest += Application_PostAuthenticateRequest;
}
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
//Do stuff here
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer serializer = new JavaScriptSerializer();
var serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);
var roles = new List<string>() { serializeModel.RoleNameCode }; // English name of role like 'Administrator'
var newUser = new CustomPrincipal(User.Identity, roles.ToArray())
{
Id = serializeModel.Id,
FirstName = serializeModel.FirstName,
LastName = serializeModel.LastName,
MiddleName = serializeModel.MiddleName,
RoleName = serializeModel.RoleName // Custom name of role i.e. in Spanish I use it to display for user
};
HttpContext.Current.User = newUser;
}
}
}
您的登录方法应该获取额外的用户数据并保存在 cookie 中
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
try
{
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
var user = User.Identity;
try
{
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
string userId = UserManager.FindByName(model.UserName)?.Id;
var s = UserManager.GetRoles(userId);
// db is EF context and UsersViews is user SQL View
var u = db.UsersViews.First(x => x.Id == userId);
var serializeModel = new CustomPrincipalSerializeModel
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
MiddleName = u.MiddleName,
RoleName = u.RoleName,
RoleNameCode = u.RoleNameCode
};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string userData = serializer.Serialize(serializeModel);
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, model.UserName, DateTime.Now, DateTime.Now.AddMinutes(20), false, userData);
string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
Response.Cookies.Add(faCookie);
return RedirectToAction("Index", "Home");
}
catch (Exception ex)
{
return View("Lockout");
}
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
catch (Exception ex)
{
throw;
}
}
在你的局部视图中,就像我在 _LoginPartial.cshtml
中的情况一样
@* here put path where you keep CustomPrincipal class *@
@using GJob.Models.Views
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<div class="form-inline my-2 my-lg-0 " style="margin-left:2em; margin-right:0em;">
<label class="form-control-sm mr-sm-2">@User.Identity.Name, @( (User as CustomPrincipal).LastName ) @( (User as CustomPrincipal).FirstName ) @( (User as CustomPrincipal).MiddleName ), @( (User as CustomPrincipal).RoleName )</label>
<a href="javascript:document.getElementById('logoutForm').submit()" class="btn btn-outline-primary btn-sm my-2 my-sm-0">Выход</a>
</div>
}
}
else
{
<form class="navbar-right">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a id="loginLink" href="@Url.Content("~/Account/Login")" class="nav-link"><span class="glyphicon glyphicon-log-in"></span> Вход</a>
</li>
</ul>
</form>
}
登录后,我在 Session[""]
变量中保留了一些用户信息。
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
try
{
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
var user = User.Identity;
try
{
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
string userId = UserManager.FindByName(model.UserName)?.Id;
var s = UserManager.GetRoles(userId);
var u = db.UsersViews.First(x => x.Id == userId);
Session["UserFullName"] = u.LastName + " " + u.FirstName.Substring(0, 1) + ". " + u.MiddleName.Substring(0, 1) + ".";
Session["UserRole"] = u.RoleName;
return RedirectToAction("Index", "Home");
}
catch (Exception ex)
{
return View("Lockout");
}
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
catch (Exception ex)
{
throw;
}
}
后来我用的像
@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<div class="form-inline my-2 my-lg-0 " style="margin-left:2em; margin-right:0em;">
<label class="form-control-sm mr-sm-2">@Session["UserFullName"] (@Session["UserRole"]) </label>
<a href="javascript:document.getElementById('logoutForm').submit()" class="btn btn-outline-primary btn-sm my-2 my-sm-0">Выход</a>
</div>
}
}
else
{
<form class="navbar-right">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a id="loginLink" href="@Url.Content("~/Account/Login")" class="nav-link"><span class="glyphicon glyphicon-log-in"></span> Вход</a>
</li>
</ul>
</form>
}
但是一旦会话结束,就没有任何值可以显示了。
所以我的问题是如何在不增加会话超时的情况下保持更新的会话变量?
谢谢!
我在这里找到了答案ASP.NET MVC - Set custom IIdentity or IPrincipal
但是我稍微调整了这个方法。
这是我的工作代码。
创建几个 类 of IPrincipal
interface ICustomPrincipal : IPrincipal
{
string Id { get; set; }
string FirstName { get; set; }
string LastName { get; set; }
string MiddleName { get; set; }
string RoleName { get; set; }
}
public class CustomPrincipal : ICustomPrincipal
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string RoleName { get; set; }
private string[] _roles; // Keep here English name of roles that ypu will use for Controller [Authorize(Roles = "Administrator, Guest")]
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
return Array.BinarySearch(_roles, role) >= 0 ? true : false;
}
public CustomPrincipal(IIdentity identity, string[] roles)
{
Identity = identity;
_roles = new string[roles.Length];
roles.CopyTo(_roles, 0);
Array.Sort(_roles);
}
}
public class CustomPrincipalSerializeModel
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string RoleName { get; set; }
public string RoleNameCode { get; set; } // English name of role like 'Administrator'
}
在Global.asax中添加
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// Add this
PostAuthenticateRequest += Application_PostAuthenticateRequest;
}
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
//Do stuff here
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
JavaScriptSerializer serializer = new JavaScriptSerializer();
var serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);
var roles = new List<string>() { serializeModel.RoleNameCode }; // English name of role like 'Administrator'
var newUser = new CustomPrincipal(User.Identity, roles.ToArray())
{
Id = serializeModel.Id,
FirstName = serializeModel.FirstName,
LastName = serializeModel.LastName,
MiddleName = serializeModel.MiddleName,
RoleName = serializeModel.RoleName // Custom name of role i.e. in Spanish I use it to display for user
};
HttpContext.Current.User = newUser;
}
}
}
您的登录方法应该获取额外的用户数据并保存在 cookie 中
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
try
{
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
var user = User.Identity;
try
{
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
string userId = UserManager.FindByName(model.UserName)?.Id;
var s = UserManager.GetRoles(userId);
// db is EF context and UsersViews is user SQL View
var u = db.UsersViews.First(x => x.Id == userId);
var serializeModel = new CustomPrincipalSerializeModel
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
MiddleName = u.MiddleName,
RoleName = u.RoleName,
RoleNameCode = u.RoleNameCode
};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string userData = serializer.Serialize(serializeModel);
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, model.UserName, DateTime.Now, DateTime.Now.AddMinutes(20), false, userData);
string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
Response.Cookies.Add(faCookie);
return RedirectToAction("Index", "Home");
}
catch (Exception ex)
{
return View("Lockout");
}
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
catch (Exception ex)
{
throw;
}
}
在你的局部视图中,就像我在 _LoginPartial.cshtml
@* here put path where you keep CustomPrincipal class *@
@using GJob.Models.Views
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<div class="form-inline my-2 my-lg-0 " style="margin-left:2em; margin-right:0em;">
<label class="form-control-sm mr-sm-2">@User.Identity.Name, @( (User as CustomPrincipal).LastName ) @( (User as CustomPrincipal).FirstName ) @( (User as CustomPrincipal).MiddleName ), @( (User as CustomPrincipal).RoleName )</label>
<a href="javascript:document.getElementById('logoutForm').submit()" class="btn btn-outline-primary btn-sm my-2 my-sm-0">Выход</a>
</div>
}
}
else
{
<form class="navbar-right">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a id="loginLink" href="@Url.Content("~/Account/Login")" class="nav-link"><span class="glyphicon glyphicon-log-in"></span> Вход</a>
</li>
</ul>
</form>
}