0

In one of my Controller's actions I set TempData["key"] = true. When I attempt to read the value upon redirecting a user to another action it always returns null. I've read all the posts available here as well as Microsoft's docs, yet nothing seems to be helping to solve my issue. I haven't got an idea what else I could do.

In ConfigureServices:

services.Configure<CookiePolicyOptions>(options =>
        {
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddDistributedMemoryCache();

        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddSessionStateTempDataProvider();

        services.AddSession();

In Configure():

app.UseSession();
app.UseMvc();  

In the first action:

TempData["value"] = true;

In the second action:

var value = TempData["value"]; // --> this is always null

Could anyone say what I'm doing wrong here?

UPDATE 1

So now the ConfigureServices() looks like this:

public void ConfigureServices(IServiceCollection services)
{

    services.AddSingleton<ITempDataProvider, SessionStateTempDataProvider>();

    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => false;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDistributedMemoryCache();

    services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddSessionStateTempDataProvider();

    services.AddSession();

    var connectionString = "connectionString";

    services.AddDbContext<PlannerContext>(o => o.UseSqlServer(connectionString));

    services.AddScoped<IPlannerRepository>(provider =>
        new PlannerRepository(provider.GetService<PlannerContext>()));

    services.AddScoped<IScheduleSpecific>(provider =>
        new ScheduleSpecific(provider.GetService<PlannerContext>()));

    services.AddSingleton<ILoggerFactory, LoggerFactory>();
}

And the Configure() method:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/error");
    }



    app.UseSession();
    app.UseMvc();



}

I still can't get a value from TempData["key"]. It keeps returning null. I don't know what else to do. I'm beginning to feel like I'm banging my head over a brick wall...

UPDATE 2

I started a new project and used the same configuration settings as above. The result is the same as I described earlier:

null TempData value

Configuration

Dependencies

aspdev
  • 145
  • 3
  • 14
  • I read the post you quote several times. None of the things mentioned there helped me and that is why I decided to ask a separate questions. Plus the post you're referring to seems to be about earlier version of ASpNetCore. – aspdev Dec 09 '18 at 18:07
  • Well, the answers over there don't make much sense. I have reopened. – H H Dec 09 '18 at 18:54
  • And FWIW, I cannot rerproduce this. I tried in a fairly small 2.1 app and the value persists, both with and without AddSession(). – H H Dec 09 '18 at 18:56
  • @HenkHolterman Thank you. What does "FWIW" mean? – aspdev Dec 09 '18 at 19:21
  • I've also added Microsoft.AspNetCore.Session(2.1.1) and MIcrosoft.Extensions.Caching.Memory(2.1.1) from NuGet. Anything else I should have on my dependency list? – aspdev Dec 09 '18 at 19:27
  • I think the next step is to create an mcve: create a new project, just the template. Add the minimum of code to reproduce the issue. List all versions and steps. SO has a help page: [mcve] – H H Dec 09 '18 at 19:35
  • 2
    After Update 2: Only now can we see that it is about an API. So cookies won't work for sure, and SessionState depends on cookies (SessionId). So I would guess TempData simply doesn't work for an API. – H H Dec 09 '18 at 20:32
  • Anything else I could do to persist the value between the two requests? – aspdev Dec 09 '18 at 20:43
  • You could cook up your own Session concept - common for autentication scenarios. But what you want to do looks like an X/Y problem (google again), you won't find anything out of the box. API calls should be stateless and independent. – H H Dec 09 '18 at 20:46

1 Answers1

1

There are two different built-in providers for temp data: SessionStateTempDataProvider and CookieTempDataProvider. The latter will directly use a cookie to persist the temp data for the user. The former will use the session state to persist the temp data. Since the session state itself also uses a cookie to identify the user session, both solutions are dependent on cookies.

Now, in a typical API situation, you are dealing with REST which is stateless by definition. That means that cookies, a mechanism to keep state, are not used with it. So you can use neither temp data nor session state within your API.

While it would be possible to set up your own temp data provider that uses e.g. a user id from your authentication to look up temp data from a central store, doing so would again introduce state into your API which is generally discouraged.

Instead, you should make sure that your API is as stateless as possible and that the client passes everything necessary with the request.

Of course, if you don’t want to do REST, you could also just require the API clients to locally store cookies.

poke
  • 369,085
  • 72
  • 557
  • 602