在.NET Core MVC应用程序中使用TempData时出现500错误

11

你好,我试图将一个对象添加到TempData并重定向到另一个控制器动作。在使用TempData时,我遇到了500错误消息。

public IActionResult Attach(long Id)
{
    Story searchedStory=this.context.Stories.Find(Id);
    if(searchedStory!=null)
    {
        TempData["tStory"]=searchedStory;  //JsonConvert.SerializeObject(searchedStory) gets no error and passes 

        return RedirectToAction("Index","Location");
    }
    return View("Index");
}


public IActionResult Index(object _story) 
{             
    Story story=TempData["tStory"] as Story;
    if(story !=null)
    {
    List<Location> Locations = this.context.Locations.ToList();
    ViewBag._story =JsonConvert.SerializeObject(story);
    ViewBag.rstory=story;
    return View(context.Locations);
    }
    return RedirectToAction("Index","Story");
}

顺便提一下,阅读可能的解决方案后,我在Configure方法中添加了app.UseSession(),在ConfigureServices方法中添加了services.AddServices(),但都没有奏效。是否有我必须注意的模糊设置?

顺便说一下,添加ConfigureServicesUseSession

ConfigureServices

 public void ConfigureServices(IServiceCollection services)
            {
                services.AddOptions();
                services.AddDbContext<TreasureContext>(x=>x.UseMySql(connectionString:Constrings[3]));
                services.AddMvc();
                services.AddSession();
            }

配置

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();
            app.UseSession();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

请发布您的 Startup.ConfigureServices 和 Startup.Configure 方法。 - fatherOfWine
我已经发布了它们。 - Bercovici Adrian
永远不会出现没有任何错误信息的500错误。查看您的日志,并了解实际的错误是什么。如果找不到解决方案,请确保在您的问题中包含完整的错误消息。 - poke
请务必仔细阅读有关正确使用TempData的方法 - Heretic Monkey
4个回答

24

在将对象分配给TempData之前,您需要对其进行序列化,因为核心只支持字符串而不支持复杂对象。

TempData["UserData"] = JsonConvert.SerializeObject(searchedStory);

通过反序列化检索对象。

var story = JsonConvert.DeserializeObject<Story>(TempData["searchedStory"].ToString())

6
这是我的问题,让我头疼不已。使用复杂对象导致我返回500错误,没有任何异常或解释说明返回的500错误的原因。将其序列化是行之有效的方法。 - FerX32
完美运行。谢谢你解救了今天 :D - Mohammed A. Fadil

5

您的ConfigureServices()方法中缺少services.AddMemoryCache();行。应该像这样:

        services.AddMemoryCache();
        services.AddSession();
        services.AddMvc();

之后,TempData应该按预期工作。

4
Asp.net Core 3 用户请注意:此解决方案不适用于您,请参考 Agrawal Shraddha 的解决方案。 - Mohammed A. Fadil
@MohammedA.Fadil 在 Mvc Core 3 应用程序中,此解决方案将有效。请在评论之前先进行研究。 - fatherOfWine
我进行了研究,你的解决方案对我无效。在不断尝试后,Agrawal Shraddha的解决方案在3.1上完美地运行了。 - Mohammed A. Fadil
1
尊敬的各位,我提供的解决方案在我的MVC.NET Core 3应用程序中运行良好。:) 因此,说“这个解决方案不适用于Asp.net Core 3用户”有点牵强,因为我正在开发的应用程序是对您的说法的明证。祝大家编程愉快!:) - fatherOfWine
不要介意,兄弟。祝你好运。 - Mohammed A. Fadil
1
@MohammedA.Fadil 我可以确认,这在Core 3.1上不起作用。 - sandy

3

我正在使用预览版的Dot net 5.0进行开发。在我的情况下,上面提到的配置都不起作用。在Dot net 5.0 MVC应用程序中,TempData导致XHR对象接收到500内部服务器错误。最后,我发现缺失的部分是AddSessionStateTempDataProvider()。

`public void ConfigureServices(IServiceCollection services)
        {
            services.AddBrowserDetection();
            services.AddDistributedMemoryCache();

            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromSeconds(120);
            });

            services.AddControllersWithViews().
                .AddSessionStateTempDataProvider();
        }`

使用TempData时添加会话很重要,因为TempData在内部使用Session变量来存储数据。此外,@Agrawal Shraddha的回答也非常有效。Asp.Net Core / Dot net 5.0不支持TempData直接存储复杂对象。相反,它必须序列化为Json字符串,并在检索时进行反序列化。
`TempData[DATA] = JsonConvert.SerializeObject(dataObject);`

并将Configure()方法设置为以下内容:

`public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseSession();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
`

要了解有关 TempData 配置设置的更多信息以使其工作,请参考以下文章: https://www.learnrazorpages.com/razor-pages/tempdata


1
添加一个TempData扩展,就像Session一样进行序列化和反序列化。
    public static class TempDataExtensions
    {
        public static void Set<T>(this ITempDataDictionary tempData, string key, T value)
        {
           string json = JsonConvert.SerializeObject(value);
           tempData.Add(key, json);
        }

        public static T Get<T>(this ITempDataDictionary tempData, string key)
        {
            if (!tempData.ContainsKey(key)) return default(T);

            var value = tempData[key] as string;

            return value == null ? default(T) :JsonConvert.DeserializeObject<T>(value);
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接