3 votes

"Session has not been configured for this application or request" en controlador Asíncrono de AspNet vNext

Greetings,

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

Randomly (sometimes yes, sometimes no), this error appears:

“Session has not been configured for this application or request”

additionally, there is a

"InvalidOperationException".

and the HttpContext.Session object is null.

I have read the documentation ( https://docs.asp.net/en/latest/fundamentals/app-state.html ) and there it indicates that if you try to access the object " Session "before using the middleware " UseSession "This exception occurs. Also in several StackOverflow threads like this one: https://stackoverflow.com/questions/29801631/unable-to-use-session-in-asp-net-vnext-project o https://stackoverflow.com/questions/33814042/using-tempdata-is-crashing-my-application among others; and they recommend re-organizing the middleware calls of the " Configure "of the class " StartUp "in such a way that the middleware " UseSession "is used before invoking the middleware " UseMvc ".

It is clear to me how important it is that invocations to middlewares in the " Configure "The request pipeline should be in a strict order so that the request pipeline reacts coherently to the middleware and to test this I have been "moving up" the call to " UseSession "and at this time the middleware " UseSession "is the first in the method " Configure "but I can't get this exception to keep occurring.

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

Also in some StackOverflow posts I have read that by placing a

"using Microsoft.AspNet.Http;"

which (in my little knowledge of C#) doesn't make much sense since the " using "by itself does nothing (unless extension methods are used), in this case, 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 get my controller to work, I have tried using the Http features, but these also randomly appear null. I have created a property to access the Session object, as well:

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

I would be grateful if anyone knows how I can deal with this problem that is keeping me awake at night.

Thank you very much.

Update:

As I posted 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 a bit the logic of the controller to leave it totally synchronous (no await calls) and the error disappears (I think the randomness I was talking about initially was due to the tests I was doing).

Although I really don't know if it's a bug, I'd really like to get everything back to asynchronous as I had it. I appreciate if anyone knows why it works being synchronous and stops working being asynchronous.

Thank you again.

5voto

rsciriano Points 1952

To use the session in an ASP.NET Core project (a.k.a ASPNET vNext, a.k.a ASPNET5) it is necessary to 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() y AddCaching() in the method ConfigureServices(IServiceCollection services) of the archive startup.cs

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

Finally, we must add a call to UseSession() just before configuring 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: I have obtained the code examples from this article where it is explained in detail but I have not had time to try it personally. Let me know if it works for you.

Update: The values of the session variables can also be accessed 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();
}

HolaDevs.com

HolaDevs is an online community of programmers and software lovers.
You can check other people responses or create a new question if you don't find a solution

Powered by:

X