【问题标题】:Request Cookie not updating when accessed in the same request context在同一请求上下文中访问时请求 Cookie 不更新
【发布时间】:2018-02-22 22:17:14
【问题描述】:

我已经查看了很多与此问题类似的问题,但没有任何问题可以解决我的问题。我将我的用户语言保存在 cookie 中。首先,它是一个 Umbraco 网站。我有一个默认控制器,每个请求都会命中以检查语言。

我做了一些计算来检查用户在控制器中应该使用什么语言,然后像下面这样设置 cookie。

 private void SetCulture(string language, bool updateCookie)
 {
     if (updateCookie)
     {
         var newCookie = new HttpCookie("currentLanguage", language) { Expires = DateTime.Now.AddDays(30) };
         Response.Cookies.Add(newCookie);
         Request.Cookies.Add(newCookie);
     }
     System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(language);
     System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
 }

目前我正在更新请求和响应 cookie。问题是在我点击控制器后,我加载了我的视图。在我看来,我使用帮助程序来获取当前的 cookie 值,但是请求中的 cookie 尚未更新并且仍保持其原始值。例如,假设用户在 EN 页面上,他们使用语言切换器更改为 FR,我使用上面的 SetCulture 方法更新控制器中的 cookie,但在我的帮助程序类中,cookie 仍然设置为原始 EN 值。 CookieHelper 在下方。

public static class CookieHelper
{
     public static string GetLanguageCookie()
     {
         var newCookie = HttpContext.Current.Request.Cookies["currentLanguage"];

         return newCookie?.Value ?? "en";
     }

     public static void UpdateLanguageCookie(string lang)
     {
         var newCookie = HttpContext.Current.Request.Cookies["currentLanguage"];
         if (newCookie?.Value != null)
         {
             newCookie.Value = lang;
             newCookie.Expires = DateTime.Now.AddDays(30);
         }
         else
         {
             CreateLanguageCookie(lang);
         }

      }

      public static void CreateLanguageCookie(string lang)
      {
          var newCookie = new HttpCookie("currentLanguage", lang) { Expires = DateTime.Now.AddDays(30) };
          HttpContext.Current.Response.Cookies.Add(newCookie);
      }
 }

下面的控制器已被删减,仅用于问题相关代码。澄清一下,该网站分为地区部分,英国、法国和德国。每个区域站点都有一组允许的语言 DE = "en,de" uk = "en" 和 fr = "fr"。我知道奇怪的设置,但我只是遵循规范。希望解释使代码更清晰。

public class BaseRenderController : RenderMvcController
    {
        public override ActionResult Index(RenderModel model)
        {
            var language = Request.UserLanguages.First().ToLowerInvariant().Substring(0, 2);
            // If true it means where on the language select screen.
            if (Request.Url.Segments.Length == 1)
            {
                if (language == "en")
                {
                    SetCulture("en", false);
                }
                else if (language == "fr")
                {
                    SetCulture("fr", false);
                }
                else if (language == "de")
                {
                    SetCulture("de", false);
                }
                else
                {
                    SetCulture("en", false);
                }
            }
            else
            {
               var currentLang = CookieHelper.GetLanguageCookie();

               if (Helpers.UrlHelper.GetRegionalSegmentFromUrl().Substring(1).ToLower() == "uk")
               {
                   SetCulture("en", true);
               }
               else if (Helpers.UrlHelper.GetRegionalSegmentFromUrl().Substring(1).ToLower() == "fr")
               {
                   SetCulture("fr", true);
               }
               else if (Helpers.UrlHelper.GetRegionalSegmentFromUrl().Substring(1).ToLower() == "de")
               {
                   if (language == "de" || currentLang == "de")
                   {
                       SetCulture("de", true);
                   }
                   else
                   {
                       SetCulture("en", true);
                   }
               }
            }


            return base.Index(model);
        }

        private void SetCulture(string language, bool updateCookie)
        {
            if (updateCookie)
            {
                var newCookie = new HttpCookie("currentLanguage", language) { Expires = DateTime.Now.AddDays(30) };
                Response.Cookies.Add(newCookie);
                Request.Cookies.Add(newCookie);
            }
            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(language);
            System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
        }
    }

【问题讨论】:

  • 你能显示控制器/动作吗?
  • @JoeWilson 我添加了控制器,它只使用了索引操作。就好像控制器和 cookie 助手在不同的上下文中有当前请求,所以更新控制器中的 cookie 不会影响助手中访问的 cookie。
  • 您不需要将 cookie 写入 Request.Cookies.Add(newCookie);,除非您正在构建发送请求。
  • 如果 URL 中已经存在文化,则不需要 cookie。见ASP.NET MVC 5 culture in route and url

标签: c# .net asp.net-mvc cookies umbraco7


【解决方案1】:

浏览器在发送请求时设置 cookie。 ASP.NET 提供从 Request 对象对 Cookie 的访问。要设置 cookie,您需要在 Response 对象上设置它。或者正如 Miscrosoft 的文档所述:

浏览器负责管理用户系统上的 cookie。 Cookies 通过 HttpResponse 对象发送到浏览器 公开一个名为 Cookies 的集合。您可以访问 HttpResponse 对象作为 Page 类的 Response 属性。任何 cookie 必须将您要发送到浏览器的内容添加到此集合中。

https://msdn.microsoft.com/en-us/library/ms178194.aspx

【讨论】:

    猜你喜欢
    • 2016-04-06
    • 2021-10-03
    • 2019-10-18
    • 2022-01-11
    • 2014-09-19
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 2021-05-23
    相关资源
    最近更新 更多