I have a project written in ASP.NET Core 3.1.
I need to set data to Session in Singleton service:
_session.SetString("some key", "some value");
I injected the session object from DI:
public OperatorService(ILogger<OperatorService> logger,
ISession session,
IOptions<AppSettings> options)
{
this._session = session;
this._logger = logger;
this._appSettings = options.Value;
}
I calls the my method as below:
public void ChangeOperatorStatus(StatusChangeRequest request)
{
try
{
_session.SetString(request.Key, request.Value);
}
catch (Exception ex)
{
_logger.LogInformation($"Exception while changing status: {ex}");
}
}
but I get the exception below :
IFeatureCollection has been disposed.\r\nObject name: 'Collection'.
and I added some code to Startup.cs's ConfigureServices method:
services.AddHttpContextAccessor();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(20);
options.Cookie.HttpOnly = true;
})
.AddDistributedMemoryCache();
And I added app.UseSession();
to the Configure method of Startup.cs.
I trid services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
and I get the session from httpContextAccessor.HttpContext.Session
but I get the same error.
Please help me, thank you.
Session.SetString method throws exception "IFeatureCollection has been disposed. Object name: 'Collection'. " in ASP.NET Core 3.1 Bookmark this question. Show activity on this post. I have a project written in ASP.NET Core 3.1.
Asp Net Core. Http Sets a String value in the ISession. The ISession. The key to assign. The value to assign. Stores user data while the user browses a web application. Session state uses a store maintained by the application to persist data across requests from a client. The session data is backed by a cache and considered ephemeral data.
In the handler method, add access to HttpContext.Request.Headers. Create a REST client that sends many requests simultaneously. The result is that eventually, a System.ObjectDisposedException will be thrown upon accessing HttpContext.Request.Headers.
c# - IFeatureCollection has been disposed. Object name: 'Collection'. going from controller to view - Stack Overflow IFeatureCollection has been disposed.
It took me a while to get this fixed. In my case, it was a 3.1 aspnetcore and it didn't worked until I turn the container function from
public async void OnPost
to
public async Task<IActionResult> OnPost
Looks like the HttpContext was disposed before it was used...
An HttpContext is the context of a single request. It provides access to the request, response properties etc of that single request. You can't cache it, it becomes invalid once that request ends.
Session is another transient thing - it lives only as long as a single user session. There's at least one session for every user of a web app. Caching one of those sessions in a singleton guarantees that
That's why using a Session makes sense for per-request middleware, not Singleton services.
Correct usage of HttpContext
The Session can only be reached through the request's context, so getting the correct session means getting the correct HttpContext. The correct way to do this is explained in David Fowler's ASP.NET Core Guidance :
❌ BAD This example stores the HttpContext in a field then attempts to use it later.
private readonly HttpContext _context;
public MyType(IHttpContextAccessor accessor)
{
_context = accessor.HttpContext;
}
public void CheckAdmin()
{
if (!_context.User.IsInRole("admin"))
{
throw new UnauthorizedAccessException("The current user isn't an admin");
}
}
✅ GOOD This example stores the IHttpContextAccesor itself in a field and uses the HttpContext field at the correct time (checking for null).
private readonly IHttpContextAccessor _accessor;
public MyType(IHttpContextAccessor accessor)
{
_accessor = accessor;
}
public void CheckAdmin()
{
var context = _accessor.HttpContext;
if (context != null && !context.User.IsInRole("admin"))
{
throw new UnauthorizedAccessException("The current user isn't an admin");
}
}
Use a Scoped service instead
Since a Singleton can't know what session to use. One option is to simply convert that service to a Scoped service. In ASP.NET Core, a request defines a scope. That's how controller actions and pipeline middleware get access to the correct HttpContext for each request.
Assuming the service is used by an action or middleware, perhaps the only change needed is to replace AddSingleton<ThatService>
with AddScoped<ThatService>
Turning the tables, or Inversion of Control
Another option is for callers of that singleton should provide the session to it. Instead of using a cached session eg :
public void SetStatus(string status)
{
_session.SetString(SessionKeys.UserStatus, "some value");
}
Ask for the session or HttpContext as a parameter :
public void SetStatus(string status,ISession session)
{
session.SetString(SessionKeys.UserStatus, "some value");
}
And have callers pass the correct session to it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With