【问题标题】:TempData lost in Edge but available in Chrome?TempData 在 Edge 中丢失但在 Chrome 中可用?
【发布时间】:2021-11-07 09:44:00
【问题描述】:

我在重定向之前在控制器中设置了一些TempData

// GET
public async Task<IActionResult> SomeAction()
{
    TempData["SomeTempData"] = "something";
    return RedirectToAction("SomeAction", "SomeController");
}

然后,在视图中SomeAction.cshtml

string someTempData = TempData["SomeTempData"] != null
    ? TempData["SomeTempData"].ToString() // Chrome can read TempData
    : ""; // Edge cannot

这在 Chrome 中有效,但我刚刚发现如果我在 Edge 中运行我的应用程序,数据不会出现在视图中。

我没有测试过其他浏览器。

为什么会这样?可以修吗?

更新

我已经尝试了 cmets 中发布的文章中的一些内容:

Startup.cs 中添加了 TempData 提供程序:

services.AddControllersWithViews()
    .AddSessionStateTempDataProvider();

没有区别。

改变了我在视图中读取 TempData 的方式:

string someTempData = TempData.Peek("SomeTempData") != null
    ? TempData.Peek("SomeTempData").ToString()
    : "";

没有区别。

更新 2

刚刚使用 Firefox(版本 92.0(64 位),全新安装)进行了测试。和 Edge 一样的问题。

Edge 版本是版本 93.0.961.44(官方构建)(64 位)

比较 cookie 提供了一些关于问题可能是什么的线索,但我需要一些帮助来解决这个问题:

在 Chrome 中,我看到六个 cookie:

.AspNet.Consent, value: "yes", size: 18
.AspNetCore.AntiForgery.{11 random characters}, value: {190 chars of encrypted data}
.AspNetCore.AntiForgery.{11 random characters}, value: {190 chars of encrypted data}
.AspNetCore.AntiForgery.{11 random characters}, value: {190 chars of encrypted data}
.AspNetCore.Session, value: {201 chars of encrypted data}
.AspNetCore.Identity.Application, value: {1126 chars of encrypted data}

在 Edge 和 FireFox 中,我只看到这两个:

.AspNetCore.Antiforgery.{11 random chars, same as one of the ones seen in Chrome}, value: {encrypted data}
.AspNetCore.Identity.Application, value: {encrypted data}

对于 Edge 和 FireFox,我无法看到 cookie 大小,但我认为它们与 Chrome 相同。

更新 3

我还是迷路了。这是我在Startup.cs 中的配置。能从中看出点什么来吗?:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
        options.HttpOnly = HttpOnlyPolicy.Always;
        options.Secure = CookieSecurePolicy.Always;
    });

    services.AddAutoMapper(typeof(Startup));

    services.AddDbContext<ApplicationDbContext>(options => 
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.Configure<IdentityOptions>(options =>
    {
        options.SignIn.RequireConfirmedAccount = true;
        options.Password.RequiredLength = 8;
        options.Password.RequireDigit = false;
        options.Password.RequireUppercase = false;
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequiredUniqueChars = 5;
        options.Lockout.MaxFailedAccessAttempts = 3;
        options.Lockout.DefaultLockoutTimeSpan = new TimeSpan(0, 15, 0);
    });

    services.AddAutoMapper(typeof(Startup));

    // Service for SendGrid:
    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<AuthMessageSenderOptions>(Configuration);

    services.AddDefaultIdentity<ApplicationUser>() // options => options.SignIn.RequireConfirmedAccount = true
        .AddRoles<ApplicationRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.ConfigureApplicationCookie(options =>
    {
        options.ExpireTimeSpan = TimeSpan.FromMinutes(120);
    });

    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromHours(8);
        options.Cookie.HttpOnly = true;
    });

    services.AddControllersWithViews()
        .AddFluentValidation();

    services.AddRazorPages()
        .AddSessionStateTempDataProvider();

    // FluentValidation:
    services.AddTransient<IValidator<Project>, ProjectValidator>();
    services.AddTransient<IValidator<Client>, ClientValidator>();

    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(ViewBagFilter));
    });

    services.AddHttpContextAccessor();
}

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

    app.UseRouting();

    app.UseCookiePolicy();
    app.UseSession();

    app.UseAuthentication();
    app.UseAuthorization();

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

【问题讨论】:

  • 您是否使用隐身/私人模式?
  • TempData 存储在 cookie 或 ASP.NET Core 的内置 Session 中(这需要额外的功能来实现负载平衡方案,因为 Session 默认情况下是进程内的,这意味着它不被其他负载平衡实例共享):您应该阅读以下内容:docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state
  • @Dai 不,我没有使用隐身模式或私人模式。我从那篇文章中尝试了几件事,但我似乎与以前的行为没有任何区别。查看更新的问题。
  • 您是否比较了 HTTP 请求和响应标头以发现任何差异?而且您使用的是基于 Chromium 的 Edge,对吗?不是旧的(而且很糟糕)基于“斯巴达”的 Edge?
  • @Stian 4096 个字符的限制适用于所有 组合 - .AspNetCore.Identity.Application cookie 的长度是多少?

标签: c# asp.net-core tempdata


【解决方案1】:

您需要在您的ConfigureServices 中添加services.AddDistributedMemoryCache();。还要确保在UseMVC() 之前配置UseCookiePolicy() 如果不起作用,请尝试以下代码:-

services.Configure<CookieTempDataProviderOptions>(options => {
    options.Cookie.IsEssential = true;
}); 

也许,TempData 提供程序和会话状态 cookie 不是必需的。

看到这个Documentation

【讨论】:

    猜你喜欢
    • 2021-09-14
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2023-03-22
    • 2016-07-01
    • 2022-08-05
    • 2016-03-05
    • 1970-01-01
    相关资源
    最近更新 更多