ASP.Net Core: Storing objects in TempData


There may come a time where you want to store non string data in your site's TempData. Upon doing this you will likely be met with the following exception.

Exception

    System.InvalidOperationException: The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer' cannot serialize an object of type 'App.AppClasses.MyTestClass'.
       at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer.EnsureObjectCanBeSerialized(Object item)
       at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer.Serialize(IDictionary`2 values)
       at Microsoft.AspNetCore.Mvc.ViewFeatures.SessionStateTempDataProvider.SaveTempData(HttpContext context, IDictionary`2 values)
       at Microsoft.AspNetCore.Mvc.ViewFeatures.TempDataDictionary.Save()
       at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter.SaveTempData(IActionResult result, ITempDataDictionaryFactory factory, HttpContext httpContext)
       at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter.OnResultExecuted(ResultExecutedContext context)
       at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__22.MoveNext()

The ASP.Net Core team made a decision to not try to automatically serialize complex data with the rationale that only the caller will truly know how it needs to be serialized in all cases (which is fair). As a frequent caller I can catch 90% (I made this number up) of my cases by serializing to JSON with JSON.Net. The following are two extension methods which will allow you to put data into the TempData and then retrieve it (these use Newtonsoft JSON.Net to serialize and deserialize).

C# Extension Methods

/// <summary>
/// Puts an object into the TempData by first serializing it to JSON.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="tempData"></param>
/// <param name="key"></param>
/// <param name="value"></param>
public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class
{
    tempData[key] = JsonConvert.SerializeObject(value);
}

/// <summary>
/// Gets an object from the TempData by deserializing it from JSON.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="tempData"></param>
/// <param name="key"></param>
/// <returns></returns>
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);
}

Leave a comment

Please note that we won't show your email to others, or use it for sending unwanted emails. We will only use it to render your Gravatar image and to validate you as a real person.