3
votes

I have an action in a Web API Controller that reads bytes async:

public HttpResponseMessage Post() {
    var response = Request.CreateResponse(HttpStatusCode.Created);
    var task = Request.Content.ReadAsByteArrayAsync().ContinueWith(t => {
        DoSomething(t.Result);
    });
    task.Wait();
    return response;
}

In my DoSomething method, I need access to HttpContext, e.g, using NHibernate's WebSessionContext. Unfortunately, HttpContext.Current is null.

I've learned I can use a closure to solve my problem:

var state = HttpContext.Current;
var task = Request.Content.ReadAsByteArrayAsync().ContinueWith(t => {
    HttpContext.Current = state;
    DoSomething(t.Result);
});

I wonder if there is a better way... shouldn't Web API have some extensions for this?

1
NHibernate session is not thread safe so passing it by means of HttpContext.Current = state; could cause issues.Răzvan Flavius Panda

1 Answers

4
votes

Try making your action asynchronous:

public async Task<HttpResponseMessage> Post() 
{
    byte[] t = await Request.Content.ReadAsByteArrayAsync();

    DoSomething(t);

    // You could safely use HttpContext.Current here 
    // even if this is a terribly bad practice to do.
    // In a properly designed application you never need to access 
    // HttpContext.Current directly but rather work with the abstractions 
    // that the underlying framework is offering to you to access whatever
    // information you are trying to access.

    // Bear in mind that from reusability and unit restability point of view,
    // code that relies on HttpContext.Current directly is garbage.

    return Request.CreateResponse(HttpStatusCode.Created);
}