我是MVC(5)的新手。为了向我的网站添加本地化支持,我在ApplicationUser : IdentityUser
现在最好的方法是什么?将此信息存储在浏览器中并确保重新创建,即使用户手动删除它也是如此?
TL;但我有时间
到目前为止我一直在尝试:
我开始在方法private async Task SignInAsync(ApplicationUser user, bool isPersistent)
中创建 Cookie ,但我注意到:
如果用户已经过身份验证并使用 .Aspnet.Applicationcookie 自动登录,则不会使用此方法,我的语言Cookie可能会同时过期(或已被删除)。
用户可以手动删除cookie,只是为了好玩。
我考虑检查它在控制器中的存在(查询记录的用户并从数据库中获取它)并且它可以工作但我需要在每个控制器中执行它。我不确定这是否正确。
有关如何解决此问题的任何建议,并保证应用程序在每个请求中都有一个有效的“语言cookie”?
答案 0 :(得分:5)
听起来像你想要的是Custom Action Filter。您可以覆盖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());
}
答案 1 :(得分:2)
对我来说,最简单的方法是创建自己的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不存在的实例中返回数据库。