Asp.Net MVC5 How to ensure that a cookie exists?

…衆ロ難τιáo~ 提交于 2019-12-03 03:55:52

It sounds to me like what you want here is a Custom Action Filter. You can override the OnActionExecuting method which means the logic is run before any action is called

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);
    }
}

Then register your attribute globally so it just becomes the default behaviour on every controller action

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new EnsureLanguagePreferenceAttribute());
}

To me, the easiest way would be to create your own Authorize attribute (since your language options are tied to an authenticated user account). Inside of your new authorize attribute, simply perform the check if the cookie exists. If it does, then life is good. Else, query the user's database profile and reissue the cookie with the stored value

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;
    }
}

To use, replace [Authorize] with [MyAuthorization] in your project.

If you don't want to mess with the [Authorize] attribute, you could create your own attribute that does the cookie checking and decorate your controller with that one as well.

One last alternative is to create your own Controller class that does the checking on the 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);
}

How to use (note that we inherit from MybaseController now)

public class HomeController : MyBaseController{
    public ActionResult Index(){
      //Language comes from the base controller class
      ViewBag.Language = Language;
      Return View();
        }

}

This method is neat because now that Language variable will be available in any controller that inherits from this new class.

Either of these will give you a single, cookie checking point. Additionally, you are only going back to the database only in the instance that the cookie does not exist.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!