HttpContext.Current is null in server-side DataPortal methods?

HttpContext.Current is null in server-side DataPortal methods?

Old forum URL: forums.lhotka.net/forums/t/12609.aspx


PeteK posted on Monday, May 05, 2014

Hi,

I'm gradually introducing CSLA into our existing application. It's a MVC / Silverlight app using WCF services hosted in IIS.

For each WCF call, the existing code creates and stores an EF DbContext in HttpContext that is then used for the duration of that call (the DbContext is created / destroyed in the HttpApplication's BeginRequest / EndRequest event handlers).

As I'm gradually adding CSLA business objects into the mix, I've come across an issue where the HttpContext.Current ends being null within the DataPortal XYZ methods. I need access to HttpContext so that my CSLA business objects (from their server-side DataPortal XYZ methods) can calls some of the pre-existing code that relies on HttpContext containing the EF DbContext used for managing database access.

Below is an example of the code I'm using:

        public async static Task<ReportQuery> ExecuteAsync(ReportCriteria criteria)
        {
             var cmd = new ReportQuery { ReportCriteria = criteria };
             cmd = await DataPortal.ExecuteAsync<ReportQuery>(cmd);
             return cmd;
        }

        protected async override void DataPortal_Execute()
        {
             // This is where System.Web.HttpContext.Current is NULL
        }

I added breakpoints to the HttpApplication's BeginRequest and EndRequest event handlers (that are wrapped around the call to my CSLA DataPortal XYZ methods), and was able to confirm that HttpContext.Current did contain a 'real' value. Unfortunately, this HttpContext does not make its way further down the chain to the CSLA DataPortal XYZ methods.

I've tried quite a few things,but no luck yet. I made sure to include the following in Web.config, to ensure that HttpContext is accessible within WCF:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

Any ideas?

Thanks,
Pete 

ajj3085 replied on Monday, May 05, 2014

I think the async dataportal method is causing you execute code to run in a new thread, which would not have access to the http context.  You can verify this by looking at the Thread.CurrentThread.ManagedThreadId property where you have the http context and you don't.

PeteK replied on Tuesday, May 06, 2014

Hi Andy,

Yep, you're right. Stepping through the code, I noticed that the HttpContext.Current was getting 'lost' when the CSLA WcfPortal makes the call to (and awaits) the BO's async DataPortal_XYZ() methods:

In WcfPortal.cs:

    public async Task<WcfResponse> Fetch(CriteriaRequest request)
    {
        .......................................
        // HttpContext.Current contains a VALUE.
        .......................................
        var fetchResponse = await processor.Fetch(fetchRequest).ConfigureAwait(false);
        .......................................
        // HttpContext.Current is now NULL.
        .......................................
    }

The above line of code calls my business object's DataPortal_Fetch() method:

    private void DataPortal_Fetch(Criteria criteria)
    {
        .......................................
        // HttpContext.Current is now NULL.
        .......................................
    } 

Is there any way to get the HttpContext to propagate through? I've tried a few things, even creating my own proxies and factories, but still no success.

Thanks,
Pete 

JonnyBee replied on Tuesday, May 06, 2014

You need to revisit your design.

When you start an asynchronous operation you have no control on how long the async operation will be running and the actual HttpRequest thread may be gone and the EF DbContext may already be Disposed while your async method is running.

So you must either

PeteK replied on Tuesday, May 06, 2014

Hi there,

Thanks for your replies.

Johhny, I might have to go with your first suggestion. I don't think your second suggestion will work for us as we're dealing with a Silverlight app, which I believe forces us to use asynchronous DataPortal calls.

Regarding the issue of HttpContext becoming null, I found this page which seems to describe the situation:

    http://blog.alextercete.com/keep-your-context-around/

It appears that calling .ConfigureAwait(false) causes HttpContext to become null, and this actually is done throughout the CSLA DataPortal code.

Cheers,
Pete 

Copyright (c) Marimer LLC