Stian
Stian

Reputation: 1602

TempData lost in Edge but available in Chrome?

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

Upvotes: 3

Views: 373

Answers (1)

Pritom Sarkar
Pritom Sarkar

Reputation: 2252

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

Upvotes: 0

Related Questions