Asp.Net MVC5如何确保cookie存在?

时间:2014-02-11 11:28:05

标签: asp.net asp.net-mvc cookies asp.net-mvc-5 asp.net-identity

我是MVC(5)的新手。为了向我的网站添加本地化支持,我在ApplicationUser : IdentityUser

中添加了一个“语言”字段

现在最好的方法是什么?将此信息存储在浏览器中并确保重新创建,即使用户手动删除它也是如此?


TL;但我有时间

到目前为止我一直在尝试:

我开始在方法private async Task SignInAsync(ApplicationUser user, bool isPersistent)中创建 Cookie ,但我注意到:

  1. 如果用户已经过身份验证并使用 .Aspnet.Applicationcookie 自动登录,则不会使用此方法,我的语言Cookie可能会同时过期(或已被删除)。

  2. 用户可以手动删除cookie,只是为了好玩。

  3. 我考虑检查它在控制器中的存在(查询记录的用户并从数据库中获取它)并且它可以工作但我需要在每个控制器中执行它。我不确定这是否正确。

    有关如何解决此问题的任何建议,并保证应用程序在每个请求中都有一个有效的“语言cookie”?

2 个答案:

答案 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不存在的实例中返回数据库。