我是MVC(5)的新手。为了给我的网站添加本地化支持,我在ApplicationUser : IdentityUser
中添加了一个"语言"字段
现在将此信息存储在浏览器中并确保重新创建的最佳方法是什么?
TL;但我有时间
到目前为止我一直在尝试:
我开始在方法private async Task SignInAsync(ApplicationUser user, bool isPersistent)
中创建cookie,但我注意到:
-
如果用户已经通过身份验证并使用.Aspnet.Applicationcookie自动登录,则不使用此方法,同时我的语言cookie可能已过期(或已删除)。
-
用户可以手动删除cookie,只是为了好玩。
我想过检查它在控制器中的存在(查询记录的用户并从数据库中获取它),它可以工作,但我需要在每个控制器中都这样做。我不确定这样做的正确方法是什么。
关于如何解决这个问题并保证应用程序在每个请求上都有一个有效的"语言cookie",有什么建议吗?
在我看来,您想要的是一个自定义操作过滤器。您可以覆盖OnActionExecuting
方法,这意味着在任何操作被称为之前,逻辑都会运行
public class EnsureLanguagePreferenceAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var langCookie = filterContext.HttpContext.Request.Cookies["LanguagePref"];
if (langCookie == null)
{
// cookie doesn't exist, either pull preferred lang from user profile
// or just setup a cookie with the default language
langCookie = new HttpCookie("LanguagePref", "en-gb");
filterContext.HttpContext.Request.Cookies.Add(langCookie);
}
// do something with langCookie
base.OnActionExecuting(filterContext);
}
}
然后全局注册您的属性,使其成为每个控制器动作的默认行为
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new EnsureLanguagePreferenceAttribute());
}
对我来说,最简单的方法是创建自己的Authorize属性(因为您的语言选项与经过身份验证的用户帐户绑定)。在新的authorize属性中,只需检查cookie是否存在即可。如果是这样,那么生活就是美好的。否则,查询用户的数据库配置文件并重新发布具有存储值的cookie
public class MyAuthorization : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//no point in cookie checking if they are not authorized
if(!base.AuthorizeCore(httpContext)) return false;
var cookie = httpContext.Request.Cookies["LanguageCookie"];
if (cookie == null) {
CreateNewCookieMethod();
}
return true;
}
}
若要使用,请在项目中将[Authorize]
替换为[MyAuthorization]
。
如果你不想破坏[Authorize]
属性,你可以创建自己的属性来进行cookie检查,并用它来装饰你的控制器。
最后一种选择是创建自己的Controller类,用于检查OnActionExecuting。
public class MyBaseController : Controller
{
public string Language {get;set;}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var cookie = filterContext.HttpContext.Request.Cookies["LanguageCookie"];
if(cookie == null){
cookie = CreateNewCookieMethod();
filterContext.HttpContext.Request.Cookies.Add(cookie);
}
Language = cookie.Value;
base.OnActionExecuting(filterContext);
}
如何使用(注意,我们现在继承自MybaseController)
public class HomeController : MyBaseController{
public ActionResult Index(){
//Language comes from the base controller class
ViewBag.Language = Language;
Return View();
}
}
这个方法很巧妙,因为现在Language
变量将在从这个新类继承的任何控制器中可用。
这两种方法中的任何一种都会给你一个cookie检查点。此外,只有在cookie不存在的情况下,才能返回数据库。