ASP.NET CoreでSessionが働かない問題

公開日:2018-12-14
最終更新:2018-12-14

発生した問題

以下のようなコードで、Homeアクションにリクエストすると、Indexビューでは"fuga"が表示される想定だった。
実際に動作させたら、なにも表示されない。SessionのラッパークラスのTempDataでも当然ダメ。

// Index.cshtml  
<h2>@ViewData["Message"]</h2>  

// Action  
public IActionResult Index()  
{  
    var str = "";  
    str = HttpContext.Session.GetString("msg");  
    ViewData["Message"] = str;  

    return View();  
}  

public IActionResult Home()  
{  
     HttpContext.Session.SetString("msg", "fuga");  
     return Redirect("/Index");  
}  

試したこと

Indexアクションを以下のようにすると、Indexビューで"fuga"が表示された。
Sessionに値を格納することはできている。

public IActionResult Index()  
{  
    var str = "";  
    HttpContext.Session.SetString("msg", "fuga");  
    str = HttpContext.Session.GetString("msg");  
    ViewData["Message"] = str;  

    return View();  
}  

Redirectするタイミングで、Sessionから保持していた値が消えているのではないかと推測。

途中経過

ブラウザで確認すると、クライアントに提供されているはずのCookie等がなにも渡されていない。
とはいえ、StartUp.csにおけるミドルウェアの記述を含め、使い方が間違っていないことは複数回確認。
リファレンス、外部サイトを回って比較しまくった。
IISExpressの設定とか、ブラウザの設定の問題かと、広範囲に渡る調査を行うも、めぼしい情報はなし。
以下、StartUp.csの状態。

    public class Startup  
    {  
        public Startup(IConfiguration configuration)  
        {  
            Configuration = configuration;  
        }  

        public IConfiguration Configuration { get; }  

        // This method gets called by the runtime. Use this method to add services to the container.  
        public void ConfigureServices(IServiceCollection services)  
        {  
            services.Configure<CookiePolicyOptions>(options =>  
            {  
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.  
                options.CheckConsentNeeded = context => true;  
                options.MinimumSameSitePolicy = SameSiteMode.None;  
            });  

            services.AddDistributedMemoryCache();  



            // Session middleware.  
            // That should be BEFORE .AddMvc()  
            services.AddSession(options =>  
            {  
                options.IdleTimeout = TimeSpan.FromMinutes(20);  
                options.Cookie.HttpOnly = true;  
            });  

            services.AddMvc()  
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)  
                .AddSessionStateTempDataProvider();  

            // Access HttpContext from custom component.  
            services.AddHttpContextAccessor();  
        }  

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.  
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
        {  
            if (env.IsDevelopment())  
            {  
                app.UseDeveloperExceptionPage();  
            }  
            else  
            {  
                app.UseExceptionHandler("/Error");  
                app.UseHsts();  
            }  

            app.UseHttpsRedirection();  
            app.UseStaticFiles();  
            app.UseCookiePolicy();  
            app.UseSession();  

            app.UseMvc(routes =>  
            {  
                routes.MapRoute(  
                    name: "default",  
                    template: "{controller=User}/{action=Login}/{id?}");  
            });  
        }  
    }  

結論

質問を投げていたstackoverflowにも書いたが、
StartUp.csapp.UseCookiePolicy()の位置が悪さをしていた。
これをUseMvc()より前に書くと、クライアントに提供するCookieが渡されないのでセッションが維持できない。
例外は出ない。
記載位置を変えたらSessionのデータは正常に保持されていた。

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
        {  
            // 略  
            app.UseHttpsRedirection();  
            app.UseStaticFiles();  

            app.UseSession();  

            app.UseMvc(routes =>  
            {  
                routes.MapRoute(  
                    name: "default",  
                    template: "{controller=User}/{action=Login}/{id?}");  
            });  

            // ここに書かないとSessionが動かない  
            app.UseCookiePolicy();  
        }  

まとめ

でもこのapp.UseCookiePolicy()、プロジェクトを新規で生成した時点で書き換え前の位置に記載されている。
リファレンスのSessionの解説ページでも同じ位置にあるし、特に順番書き換えないとダメとも書いてないし、特にエラーを吐くわけでもなく、静かにクライアントにCookieが渡らないだけ。
おかげで解決まで1日半かかった。
リファレンスを信じてはいけないって完全に罠だよなぁ…。
マイクロソフトに振り回された…。

記事が少しでもいいなと思ったらクラップを送ってみよう!
18
+1
@showyleeの技術ブログ

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする