ASP.NET Core MVC - TempDataを使う

ASP.NET Core MVCの勉強の記録です。

今回はTempDataを使ってみたいと思います。いつものようにDocsを参考にしています。

ASP.NET Core でのセッションとアプリの状態 | Microsoft Docs

StartupクラスでTempDataを構成する

まずはTempDataを使うために準備します。と言ってもStartup.ConfigureServicesでAddMvcメソッドを呼び出すだけでいいみたいです。

public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        services.AddMvc();

        services.Configure<CookieTempDataProviderOptions>(options => {
            // TempDataのクッキーの名前を変えるなら
            options.Cookie.Name = "temp";
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
        app.UseMvcWithDefaultRoute();
    }
}

コード中のコメントに「TempDataのクッキー」とありますが、CoreではないMVCを使っていた方は疑問に思うかもしれません。詳しくは後述します。

TempDataの読み書き

TempDataに文字列や数値を読み書きする場合は従来と変わりません。

// TempDataに文字列を書き込む
TempData["key"] = "Hoge";

// TempDataから文字列を読み込む
var value = (string)TempData["key"];

ただTempDataにオブジェクトを直接読み書きすることはできないようです。

セッションと同じようにJSON文字列として読み書きする拡張メソッドを用意すればいいのかな。

// TempDataにオブジェクトを読み書きする拡張メソッドを用意する
public static class TempDataDictionaryExtensions {
    // TempDataにオブジェクトを書き込む
    public static void SetObject<TObject>(this ITempDataDictionary tempData, string key, TObject obj) {
        var json = JsonConvert.SerializeObject(obj);

        // JSON文字列として書き込む
        tempData[key] = json;
    }

    // TempDataからオブジェクトを読み込む
    public static TObject GetObject<TObject>(this ITempDataDictionary tempData, string key) {
        // JSON文字列として読み込む
        var json = (string)tempData[key];

        return string.IsNullOrEmpty(json)
            ? default(TObject)
            : JsonConvert.DeserializeObject<TObject>(json);
    }
}

// 用意した拡張メソッドを使う
// TempDataにSampleクラスを書き込む
TempData.SetObject("key", new Sample());

// TempDataからSampleクラスを読み込む
TempData.GetObject<Sample>("key");

TempDataとクッキー

ASP.NET Core 2.0からデフォルトではTempDataのストア(格納先)にクッキーが使われるようになりました。

クッキーに格納されるデータは暗号化されるとのことです。

またTempDataとCookieのHTTPヘッダの関係は、

  • TempDataに書き込むとクッキーが追加される(Set-Cookieされる)
  • TempDataから読み込むとクッキーが削除される(空のクッキーでSet-Cookieされる)

といった動きになっていました。

TempDataのストアをセッションにする

TempDataのストア(格納先)をセッションにする場合は、Statupクラスでセッションを使うように構成しつつ、AddSessionStateTempDataProviderメソッドを使います。

public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        // サービスにセッションを追加
        services.AddSession(options => {
            // セッションクッキーの名前を変えるなら
            options.Cookie.Name = "session";
        });

        // MVC関連のサービスを追加
        services.AddMvc()
            // TempDataのストアをセッションにする
            .AddSessionStateTempDataProvider();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
        // セッションを使う
        app.UseSession();

        app.UseMvcWithDefaultRoute();
    }
}

クッキーとセッションの使い分けはケースバイケースだろうなと思いますが、ちょっと悩みそう。

以上TempDataの基本的な使い方でした。