BrilBroeder
BrilBroeder

Reputation: 1579

Asp.Net core Tempdata and redirecttoaction not working

I have a method in my basecontroller class that adds data to tempdata to display pop-up messages.

protected void AddPopupMessage(SeverityLevels severityLevel, string title, string message)
{
    var newPopupMessage = new PopupMessage()
    {
        SeverityLevel = severityLevel,
        Title = title,
        Message = message
    };
    _popupMessages.Add(newPopupMessage);
    TempData["PopupMessages"] = _popupMessages;
}

If the action returns a view, this works fine. If the action is calling a redirectotoaction I get the following error.

InvalidOperationException: The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer' cannot serialize an object of type

Any thoughts ?

Upvotes: 39

Views: 29506

Answers (4)

FatalError
FatalError

Reputation: 964

In my case, I was getting issues in following script

TempData["Message"] = _localizer["User has been registered successfully"];
return RedirectToAction("Register");

_localizer was returning an object instead of string, so I changed it to following

TempData["Message"] = _localizer["User has been registered successfully"].Value;
return RedirectToAction("Register");

Which fixed the issue (might help someone).

Upvotes: 0

Chris Pratt
Chris Pratt

Reputation: 239200

TempData uses Session, which itself uses IDistributedCache. IDistributedCache doesn't have the capability to accept objects or to serialize objects. As a result, you need to do this yourself, i.e.:

TempData["PopupMessages"] = JsonConvert.SerializeObject(_popupMessages);

Then, of course, after redirecting, you'll need to deserialize it back into the object you need:

TempData["PopupMessages"] = JsonConvert.DeserializeObject<List<PopupMessage>>(TempData["PopupMessages"].ToString());

Upvotes: 59

pwhe23
pwhe23

Reputation: 1334

I was trying to serialize an Exception object to TempData and ended up having to create my own TempDataSerializer to get it to work (I was migrating some existing code to Core).

// Startup.cs
services.AddSingleton<TempDataSerializer, JsonTempDataSerializer>();

// JsonTempDataSerializer.cs
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;

public class JsonTempDataSerializer : TempDataSerializer
{
    private readonly JsonSerializer _jsonSerializer = JsonSerializer.CreateDefault(new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All, // This may have security implications
    });

    public override byte[] Serialize(IDictionary<string, object>? values)
    {
        var hasValues = values?.Count > 0;
        if (!hasValues)
            return Array.Empty<byte>();

        using var memoryStream = new MemoryStream();
        using var writer = new BsonDataWriter(memoryStream);

        _jsonSerializer.Serialize(writer, values);

        return memoryStream.ToArray();
    }

    public override IDictionary<string, object> Deserialize(byte[] unprotectedData)
    {
        using var memoryStream = new MemoryStream(unprotectedData);
        using var reader = new BsonDataReader(memoryStream);

        var tempDataDictionary = _jsonSerializer.Deserialize<Dictionary<string, object>>(reader)
            ?? new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

        return tempDataDictionary;
    }
};

Upvotes: 3

David Barrows
David Barrows

Reputation: 778

Another scenario where this type of error happened to me was upgrading from AspNetCore 2.2 to 3.0 - and, where I had AzureAD as an OpenID Connect provider - when it would try to process the AzureAD cookie, it threw an exception the TempDataProvider and complained that it could not serialize a type of Int64. This fixed:

    services.AddMvc()
    .AddNewtonsoftJson(options =>
           options.SerializerSettings.ContractResolver =
              new CamelCasePropertyNamesContractResolver());

https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#newtonsoftjson-jsonnet-support

Upvotes: 2

Related Questions