Asp.Net core Tempdata和redirecttoaction不起作用

问题描述 投票:0回答:4

我的基本控制器类中有一个方法,可以将数据添加到临时数据以显示弹出消息。

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;
}

如果该操作返回一个视图,则效果很好。如果该操作正在调用重定向操作,我会收到以下错误。

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

有什么想法吗?

asp.net-core-2.2 tempdata redirecttoaction
4个回答
55
投票

TempData
使用
Session
,它本身也使用
IDistributedCache
IDistributedCache
没有能力接受对象或序列化对象。因此,您需要自己执行此操作,即:

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

然后,当然,重定向后,您需要将其反序列化回您需要的对象:

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

2
投票

我遇到此类错误的另一个场景是从 AspNetCore 2.2 升级到 3.0 - 并且,我将 AzureAD 作为 OpenID Connect 提供程序 - 当它尝试处理 AzureAD cookie 时,它抛出了 TempDataProvider 异常并抱怨说它无法序列化 Int64 类型。此修复:

    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


1
投票

我试图将 Exception 对象序列化为 TempData,最终不得不创建自己的 TempDataSerializer 才能使其正常工作(我正在将一些现有代码迁移到 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;
    }
};

0
投票

就我而言,我在以下脚本中遇到问题

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

_localizer
返回一个对象而不是字符串,所以我将其更改为以下

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

这解决了问题(可能对某人有帮助)。

© www.soinside.com 2019 - 2024. All rights reserved.