简体   繁体   中英

Web API Request is null in ExecuteAsync method of ApiController

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).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM