CallContext.LogicalGetData is not working in reponse GlobalResponseFilters

Since version 5.0.0 the method call "CallContext.LogicalGetData(…) " returns always null if one call it from a global response filter.

Please try it with this code and the project template “Service Stack Self Host Empty”:

namespace SelfHost1
{
    class Program
    {
        static void Main(string[] args)
        {
            var appHost = new AppHost();
            "ServiceStack Self Host with Razor listening at http://127.0.0.1:8088".Print();

            appHost.GlobalRequestFilters.Add((req, resp, dto) => CreateCallContext());
            appHost.GlobalResponseFilters.Add((req, resp, dto) => DeleteCallContext());

            appHost.Init();
            appHost.Start("http://*:8088/");

            Process.Start("http://127.0.0.1:8088/");

            Console.ReadLine();
        }

        private static void CreateCallContext()
        {
            CallContext.LogicalSetData("MyCallContext", new Object());
        }

        private static void DeleteCallContext()
        {
            var o = CallContext.LogicalGetData("MyCallContext");   // <----- this should not be null !!!
            if(o == null) 
                throw new Exception("This exception is always thrown");
        }
    }
}

Due to this issue the container adapter from “Autofac.Extras.ServiceStack” is not working. I fixed this by using “HostContext.RequestContext.Items” instead of the “CallContext”. But I read about an older issue: https://github.com/ServiceStack/Issues/issues/311. Is this still a problem for the workaound?

FYI this works if you create the context from PreRequestFilters instead, e.g:

appHost.PreRequestFilters.Add((req, resp) => CreateCallContext());
appHost.GlobalResponseFilters.Add((req, resp, dto) => DeleteCallContext());

So it’s created before the first await “Thread Hop” for that request.

The referenced issue is still an issue with async and SmartThreadPool HttpListener hosts but it’s less of an issue from v5.0.0 given SmartThreadPool has been moved to ServiceStack.NetFramework so all HttpListener Self Hosts in ServiceStack.dll uses the .NET ThreadPool.

But yeah you can use RequestContext.Instance.Items if you need static access to request data, but I’d still recommend using IRequest.Items for attaching per-request data whenever possible where it “floats the state” throughout the request pipeline instead of relying on magical async state thread constructs.

1 Like