4

I am trying to access the Request property in my ApiController-derived class.

For some reason, Request is null in ExecuteAsync method. I've seen the other questions, so before you ask:

  • I am not initializing the controller by calling the constructor, it's a regular HTTP POST API call from an external device.
  • I've tried the same request locally with Fiddler, the behavior is identical.
  • I am not unit testing.
  • Before hitting the ExecuteAsync method, my request passes through a delegating handler, and in the delegating handler, my request object exists (I even add some properties without any problem).
  • At the last line of delegating handler, I call return await base.SendAsync(request, cancellationToken); without a problem and request exists.
  • Right after than in API controller, HttpContext.Current.Request is not null and accessible without problem.
  • In API controller, RequestContext is not null and accessible without problem.
  • In that same line, Request is null.

Why would this occur? I'm on Web API 2.2 (and MVC 5, if relevant).

4
  • If possible, can you show your POST API call? It might be that the external device is not forming the request properly. Did you try testing the API with a Postman or any REST client? Commented Mar 14, 2017 at 9:48
  • @SouvikGhosh I've just tried with Fiddler upon your comment. Unfortunately, it's still the same. Commented Mar 14, 2017 at 9:56
  • The RequestContext is a part by the Request (can also be obtained by Request.GetRequestContext()). Can you check how the request is created at the client side? Also, you may check HttpContext which can also give you information about individual requests. Commented Mar 14, 2017 at 10:24
  • @SouvikGhosh what do you mean by the client side? I've already tried with two different clients, they are regular HTTP requests with nothing special. I'm pretty much sure it's not the client. Commented Mar 14, 2017 at 11:00

1 Answer 1

4
+50

This is probably due to the fact that you're trying to access HttpContext while working with async/await.

So, you have two options:

  1. Access the request via the ExecuteAsync method 'HttpControllerContext' parameter - controllerContext.Request.
  2. Make sure your web.config is targeting .NET 4.5 and update appSettings with aspnet:UseTaskFriendlySynchronizationContext set to true.

You can read more here - Using HttpContext Safely After Async in ASP.NET MVC Applications.

To better understand what's going on under the hood, I'd recommend:

  1. Understand what is SynchronizationContext - ExecutionContext vs SynchronizationContext
  2. Understand how it is related to ASP.NET - Understanding the SynchronizationContext in ASP.NET.

In a very very high level: in a synchronous server implementations, where the entire request is processed by the same thread, the execution context is stored using TLS (thread local storage), means HttpContext is available anywhere in your code.

In an asynchronous server implementation (async/await), the request may be processed by several threads, and there's a need to pass the execution context between those threads.

Sign up to request clarification or add additional context in comments.

2 Comments

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> in the web.config
Option 2 seemed easier but it didn't work for some reason (it was still null). Option 1 worked. I'd be happy to learn about the reason though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.