I’ve finished updating everything from SS 6 to SS 8.5. Moved everything to the new Configure.X.cs type startup.
But one last strange issue remains: I keep getting an IFeatureCollection has been disposed error.
And I just realized why: my current request is operating on the LAST requests HttpContext.
Here is the error:
[00:07:15 ERR] IFeatureCollection has been disposed.
Object name: 'Collection'.
System.ObjectDisposedException: IFeatureCollection has been disposed.
Object name: 'Collection'.
at Microsoft.AspNetCore.Http.Features.FeatureReferences`1.ThrowContextDisposed()
at Microsoft.AspNetCore.Http.Features.FeatureReferences`1.ContextDisposed()
at Microsoft.AspNetCore.Http.DefaultHttpContext.get_RequestServices()
at ServiceStack.Host.NetCore.NetCoreRequest.TryResolve[T]() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Host/NetCore/NetCoreRequest.cs:line 55
at ServiceStack.ServiceStackHost.GetCacheClient(IRequest req) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/ServiceStackHost.Runtime.cs:line 1078
at ServiceStack.Service.get_Cache() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Service.cs:line 70
at ServiceStack.Service.SessionAs[TUserSession]() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Service.cs:line 169
... redacted
at LENSSX.ServiceInterface.InvestigationService.Get(GetInvestigation get) in C:\Projects\LENSS\src\LENSSX.ServiceInterface\InvestigationService.cs:line 176
at ServiceStack.Host.ServiceRunner`1.ExecuteAsync(IRequest req, Object instance, TRequest requestDto) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Host/ServiceRunner.cs:line 149
Here is the last HTTP Get that is retrieved from my dashboard:
When I go to the page that loads a singular Investigation (GetInvestigation endpoint is hit), and I put a breakpoint at the exact line of the error generating the response, the results are interesting:
The response is already closed, but if you look at the Dto … it’s of type QueryResponse. Which is from the prior call loaded from my dashboard (a SearchInvestigations api call)
But I’m in a completely different service endpoint, returning a single InvestigationResponse (not a list).
Why and how on earth would this service endpoint hit essentially have the OLD api calls HttpContext, that’s already been disposed?
Maybe I misregistered something in the new bootstrap / ioc setup?
This is happening when you’re retrieving a session from the cache?
The session should only hold serializable data, are you trying to store dependencies in it?
Or are you trying to call this outside the context of a request? e.g. in a Background Thread or after the request has completed? maybe you’ve not awaited all your async methods?
This is happening when you’re retrieving a session from the cache?
Yes - starts at SessionAs, which attempts to pull ICacheClient from services, but everything is disposed. The HttpContext / response is closed, because it’s the old HttpContext (from the previous api call)
The session should only hold serializable data, are you trying to store dependencies in it?
Not that I know of, using services.Add syntax for all service registration
Or are you trying to call this outside the context of a request? No - this is in a Singleton Helper class down the call chain from the service request
e.g. in a Background Thread or after the request has completed?
maybe you’ve not awaited all your async methods? I’ve checked, double checked, triple checked the entire call chain
Could this happen if a singleton is holding on to some old HttpContext?
It’s happening when you’re trying to access the RequestContext:
In order to access the cache in order to access the Session. I can only imagine it’s been disposed is if you’re trying to access it outside the Request Context, i.e. outside of the HTTP Worker thread that’s processing the Request (e.g. executing the API).
Could be the issue as you can’t access the RequestContext from a singleton context, i.e. you need to ensure your static helper methods do not retain static variables to non singleton instances.
It ended up being a set of rogue Singleton registrations that was storing the first request context (which was disposed).
Thank you for your help! This SS 8.5 update was a lot larger than I thought it would be, but we got through it.
The last piece I can’t figure out is why SS chose to use the default /api namespace in its recent updates (instead of the /json/reply). Luckily we don’t have an external clients (yet), but we will soon. Trying to figure out what root namespace to use, if any. I guess I could just remove any prefix and have /MyEntity.
You can learn about the JSON /api pre-defined route in the v6 Release Notes, which was added more than 3 years ago now. At that point, /api became the preferred pre-defined routes for invoking JSON APIs without user-defined routes, whilst the previous /json/reply was continued to be supported for backwards compatibility.
In ServiceStack Routing the pre-defined routes could be implemented with just a handler that could intercept requests at runtime, but with Endpoint Routing we have to preemptively declare every route for every API against its primary HTTP Method on Startup. This is only done for newer /api pre-defined routes as the API route pollution required to register a new endpoint route for every API in every registered content-type format for every HTTP verb is not feasible.