3

I am setting some TempData in the controller before redirecting:

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

And then, in the View SomeAction.cshtml:

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

This is working in Chrome, but I just found out that the data is not present in the view if I run my app in Edge.

I have not tested other browsers.

Why is this happening? Can it be fixed?

Update

I have tried some things from the article posted in the comments:

Added TempData provider in Startup.cs:

services.AddControllersWithViews()
    .AddSessionStateTempDataProvider();

Made no difference.

Changed the way I read the TempData in the view:

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

Made no difference.

Update 2

Just tested with Firefox (version 92.0 (64-bit), fresh install). Same problem as Edge.

Edge version is Version 93.0.961.44 (Official build) (64-bit)

Comparing the cookies gave some clue as to what the problem might be, but I need some help figuring it out:

In Chrome, I see six cookies:

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

In Edge and FireFox, I only see these two:

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

For Edge and FireFox, I wasn't able to see the cookie sizes, but I assume they are the same as for Chrome.

Update 3

I'm still lost. Here is my config in Startup.cs. Can something be figured out from it?:

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();
    });
}
Stian
  • 1,522
  • 2
  • 22
  • 52
  • Are you using Incognito/Private mode at all? – Dai Sep 11 '21 at 04:25
  • `TempData` is stored in either cookies or ASP.NET Core's built-in `Session` (which requires extra functionality for load-balanced scenarios, as `Session` is in-proc by default which means it isn't shared by other load-balanced instances): you should read this: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/app-state – Dai Sep 11 '21 at 04:26
  • @Dai No, I'm not using Incognito or Private mode. I tried a couple of things from that article, but I can't seem to make any difference from the previous behaviour. See updated question. – Stian Sep 11 '21 at 06:29
  • Have you compared the HTTP request and response headers to find any differences? And you are using the Chromium-based Edge, right? Not the old (and awful) "Spartan"-based Edge? – Dai Sep 11 '21 at 06:49
  • @Dai Please see update 2. – Stian Sep 11 '21 at 07:19
  • What is the actual length of each cookie? It's possible you're hitting the 4096-character cookie length limit. – Dai Sep 11 '21 at 07:33
  • @Dai Biggest one is 1126 chars. – Stian Sep 11 '21 at 07:40
  • Did you clear/remove the cookies before this test? – Luuk Sep 11 '21 at 07:42
  • 1
    @Stian The 4096 char limit is for all cookies **combined** - what is the length of the `.AspNetCore.Identity.Application` cookie? – Dai Sep 11 '21 at 07:46
  • @Dai Yes, cookies was cleared before the test. The combined size of all cookies seen in Chrome is 1915. For the two seen in Edge and Chrome, it's less than that. The `.AspNetCore.Identity.Application` cookie is 1126 long. – Stian Sep 11 '21 at 07:49
  • @Stian You're saying the `.AspNetCore.Identity.Application` cookie is exactly 1126 chars in all 3 browsers: Chrome, Firefox, _and_ MS Edge? – Dai Sep 11 '21 at 07:54
  • @Dai No, I didn't see the length in Edge or FireFox. I found out now: In Edge, it's 1116 and in FireFox 1094. The first 27 chars are identical in all three browsers, so I assumed it was the same for them all... – Stian Sep 11 '21 at 08:01
  • I'm morbidly curious - please post your project to a new git repo (or a GitHub Gist if you can reduce it down to a single `.cs` file) and share the link so we can try to reproduce it. – Dai Sep 11 '21 at 08:05
  • @Dai I have never used GitHub before. I will look into it after work today (in about 9-10 hours). Also, my solution is rather big, so I will try to make a trimmed down version, keeping only this bug. – Stian Sep 11 '21 at 08:33
  • @Dai Looked into GitHub. Couldn't make much sense of it. Will try again. – Stian Sep 11 '21 at 21:05
  • @Dai I gave up on GitHub. But I think the problem might be in `Startup.cs`, because I tested the `TempData` functionality elsewhere in my app too, and got the same result. I added my config to the question in update 3. – Stian Sep 12 '21 at 05:13

1 Answers1

0

You will need to add services.AddDistributedMemoryCache(); in your ConfigureServices.also makesure UseCookiePolicy()being configured before UseMVC() if not work,then try the below code:-

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

Maybe, TempData provider and session state cookies aren't essential.

See this Documentation

Pritom Sarkar
  • 2,154
  • 3
  • 11
  • 26