【发布时间】:2018-04-15 21:27:00
【问题描述】:
这是我在 StackOverflow 中的第一个问题 :) 所以请不要评判我强 :) 好的。我们开始吧。
我是 ASP.NET MVC 框架的新手,并试图在我的网站中实现多语言。所以我在 _LoginPartial.cshtml 中添加了下拉语言列表:
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">@(MEDONET.Resources.IndexTexts.Language)<b class="caret"></b></a>
<ul class="dropdown-menu">
<li>@Html.ActionLink("Кыргызча", "Change", "Language", new { lang = "ky" }, null)</li>
<li>@Html.ActionLink("Русский", "Change", "Language", new { lang = "ru" }, null)</li>
<li>@Html.ActionLink("English", "Change", "Language", new { lang = "en" }, null)</li>
<li>@Html.ActionLink("O'zbekcha", "Change", "Language", new { lang = "uz" }, null)</li>
</ul>
</li>
如您所见,我将选定的语言缩写传递给语言控制器的 Change 方法。在 LanguageController 中,我的代码如下所示:
public ActionResult Change(string lang)
{
if (lang != null)
{
if (User.Identity.IsAuthenticated)
{
//var user = _userManager.FindByName(User.Identity.Name);
//_userManager.AddClaim(user.Id, new Claim("Language", lang));
//var claims = _userManager.GetClaims(user.Id);
////User.RemoveClaimIfExists("Language");
////var claims = new List<Claim>();
ApplicationDbContext mycontext = new ApplicationDbContext();
UserStore<ApplicationUser> mystore = new UserStore<ApplicationUser>(mycontext);
ApplicationUserManager UserMan = new ApplicationUserManager(mystore);
//ApplicationUser _user = UserMan.FindById(User.Identity.GetUserId());
UserMan.AddClaim(User.Identity.GetUserId(), new Claim("Language", lang));
//UserMan.RemoveClaim(User.Identity.GetUserId(), User.GetClaim("Language"));
//User.AddClaim(lang);
}
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);
HttpCookie cookie = new HttpCookie("Language");
cookie.Value = lang;
Response.Cookies.Add(cookie);
return Redirect(Request.UrlReferrer.ToString());
}
return Redirect(Request.UrlReferrer.ToString());
}
如您所见,我尝试了很多不同的方法来实现该功能。经过一天的折磨,它开始起作用了。但我不确定我的 Frankenshtain 是向 AspNetUserClaims 表写入声明的最佳方式。所以这是我的第一个问题:
1) 如何改进我的索赔代码编写?
第二个问题很接近第一个问题:
2) 如何更新现有用户声明?
对于我的知识水平问题,最后第三个明显的问题是:
3) 如何读取存储的声明?
一旦设置声明需要在接下来的会话中阅读。因此,我创建了 Claims 类,并在其中添加了这个
public static string GetClaimValue(this IPrincipal currentPrincipal, string key)
{
var identity = currentPrincipal.Identity as ClaimsIdentity;
if (identity == null)
return null;
var claim = identity.Claims.FirstOrDefault(c => c.Type == key);
return claim?.Value;
}
编码并从 AccountController 的 Login 方法调用它:
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
HttpCookie cookie = new HttpCookie("Language");
string lang = GetClaimValue("Language");
if (lang == null) // language was not selected befor
lang = "ru";
Response.Cookies.Add(cookie);
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cookie.Value);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(cookie.Value);
return RedirectToLocal(returnUrl);
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);
}
}
你可能猜到我总是得到俄语而不是吉尔吉斯语,它存储在 AspNetUserClaims 表中的缩写“ky”。
就是这样 :) 我希望这里没有太多的桌面谈话。请帮帮我!
【问题讨论】:
标签: c# asp.net asp.net-mvc asp.net-mvc-4 claims