1. ホーム
  2. c#

複合オブジェクトをTempDataに格納する

2023-09-05 07:20:49

質問

TempDataを使用してリダイレクト後のアクションにデータを渡そうとしたところ、以下のようになりました。

if (!ModelState.IsValid)
{
    TempData["ErrorMessages"] = ModelState;
    return RedirectToAction("Product", "ProductDetails", new { code = model.ProductCode });
}

を実行しましたが、残念ながら以下のようなメッセージが出て失敗しています。

' System.InvalidOperationExceptionMicrosoft.AspNet.Mvc.SessionStateTempDataProvider' をシリアライズすることはできません。 オブジェクトをシリアライズすることはできません。 'ModelStateDictionary' をセッション状態にシリアライズすることはできません'。

での問題を発見しました。 にあるMVCプロジェクト で問題を発見しましたが、このエラーが発生する理由は説明されているものの、実行可能な代替案が見当たりません。

1 つの選択肢は、オブジェクトを json 文字列にシリアライズして、それをデシリアライズして、その後に ModelState . これは最良の方法でしょうか?私が考慮する必要がある潜在的なパフォーマンスの問題はありますか?

最後に、複雑なオブジェクトをシリアライズする方法、あるいは TempData ?

どのように解決するのですか?

このように、拡張メソッドを作成することができます。

public static class TempDataExtensions
{
    public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class
    {
        tempData[key] = JsonConvert.SerializeObject(value);
    }

    public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class
    {
        object o;
        tempData.TryGetValue(key, out o);
        return o == null ? null : JsonConvert.DeserializeObject<T>((string)o);
    }
}

と、以下のように使うことができます。

例えば objectAClassA . これを上記の拡張メソッドを使ってtempデータ辞書に追加すると、次のようになります。

TempData.Put("key", objectA);

そして、それを取り出すには次のようにします。

var value = TempData.Get<ClassA>("key") ここで value の型が取得されます。 ClassA