"Session has not been configured for this application or request" in AspNet Asynchronous driver vNext

3

Greetings,

I appreciate help with the next issue that is already killing my head. Using AspNet vNext (1.0.0-rc1-update1) I have had problems accessing session data from a controller for WebApi.

Randomly (sometimes, sometimes not), this error appears:

  

"Session has not been configured for this application or request"

additionally, a

  

"InvalidOperationException"

and the HttpContext.Session object is null.

I have read the documentation ( link ) and there it indicates that if it is about Access the object " Session " before using the middleware " UseSession " this exception occurs. Also in several StackOverflow threads (English) like this: link or link among others; and recommend re-organizing calls to the middleware of the " Configure " method of the " StartUp " class in such a way that middleware " UseSession "Be used before invoking middleware" UseMvc ".

I am clear that it is important that the invocations to the middlewares in the " Configure " method be in a strict order in such a way that the request pipeline reacts coherently to the middlewares and to try I have been "uploading" the call to " UseSession " and at this moment the middleware " UseSession " is the first one in the method " Configure "But I can not get this exception to continue happening.

Initially I thought that trying to use the object "session" from a controller for WebApi could be the cause of the error, however, as I said, this error does not always occur randomly.

Also in some StackOverflow posts I read that placing a

  

"using Microsoft.AspNet.Http;"

which (in my little knowledge of C #) does not make much sense since the " using " alone does not do anything (unless extension methods are used), for that matter, the " using Microsoft.AspNet.Http; " has no effect, in fact, both "CodeMaid" and "ReSharper" mark this line as " RedundantUsingDirective ".

As an additional measure to try to make my controller work, I tried to use the Http features, but these also appear null randomly. I have created a property to access the Session object, like this:

protected ISession Session => (HttpContext.Session ?? HttpContext.Features.Get<ISession>())??HttpContext.Features.Get<ISessionFeature>()?.Session;

I appreciate if anyone knows how I can deal with this problem that no longer lets me sleep.

Thank you very much.

Update:

As I put in the comments, I found that this error only occurs when the controller where I try to access the session object has asynchronous operations (Async / Await). I have changed the logic of the controller a bit to make it completely synchronous (without await calls) and the error disappears (I think the randomness I initially spoke was due to the tests I was doing).

Although I really do not know if it is a bug, I would really like to leave everything asynchronous again as I had it. I appreciate if someone knows why it works being synchronous and stops working asynchronously.

Thanks again.

    
asked by Camilo Bernal 09.03.2016 в 01:21
source

1 answer

5

To use the session in an ASP.NET Core project (a.k.a ASPNET vNext, a.k.a ASPNET5) you must add the reference Microsoft.AspNet.Session

Then you have to configure the use of sessions in the OWIN pipeline by adding the calls to AddSession() and AddCaching() in the method ConfigureServices(IServiceCollection services) of the file startup.cs

// Add MVC services to the services container.
services.AddMvc();
services.AddCaching(); // Adds a default in-memory implementation of     IDistributedCache
services.AddSession();

Finally, you have to add a call to UseSession() just before configuring the Mvc routes

// IMPORTANT: This session call MUST go before UseMvc()
app.UseSession();

// Add MVC to the request pipeline.
app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller}/{action}/{id?}",
        defaults: new { controller = "Home", action = "Index" });

    // Uncomment the following line to add a route for porting Web API 2 controllers.
    // routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
});

This way you will be able to use the session in your controllers

public class HomeController : Controller
{
    public IActionResult Index()
    { 
        HttpContext.Session.SetString("Test", "Ben Rules!");
        return View();
    }

    public IActionResult About()
    {
        ViewBag.Message = HttpContext.Session.GetString("Test");

        return View();
    }
}

Note: The code examples I got from this article in English where they explain it in detail but I have not had time to try it personally. You'll already know if it works for you.

Update: You can also access the values of the session variables from an asynchronous task using async/await

public async Task<IActionResult> About()
{
    var task = new Task<string>(() => {
        var count = HttpContext.Session.GetInt32("Contador");

        if (count.HasValue)
            count++;
        else
            count = 1;

        HttpContext.Session.SetInt32("Contador", count.Value);
        return $"Mensaje desde tarea asíncrona [{count}]";
    });
    task.Start();

    ViewData["Message"] = await task;
    return View();
}
    
answered by 09.03.2016 в 10:11