title: Web Api 2 get controller and action name in OWIN middleware?
body: <p>How can I retrieve the api controller name and api action name inside a piece of custom OWIN middleware? I can do it inside of a message handler like so:</p>
  
  <pre><code>var config = request.GetConfiguration();
  var routeData = config.Routes.GetRouteData(request);
  var controllerContext = new HttpControllerContext(config, routeData, request);
  request.Properties[HttpPropertyKeys.HttpRouteDataKey] = routeData;
  controllerContext.RouteData = routeData;
  var controllerDescriptor = new
  DefaultHttpControllerSelector(config).SelectController(request);
  controllerContext.ControllerDescriptor = controllerDescriptor;
  var actionMapping = new ApiControllerActionSelector().SelectAction(controllerContext);
  
  //controller name
  controllerDescriptor.ControllerName
  //action name
  actionMapping.ActionName
  </code></pre>
  
  <p><strong>Update:</strong>
  Here is my current piece of OWIN middleware. How can I get the controllerName and actionName within this code?</p>
  
  <pre><code>using AppFunc = Func&lt;IDictionary&lt;string, object&gt;, Task&gt;;
  
  public class LoggingMiddleware
  {
      private readonly AppFunc _next;
      private static readonly ILog RequestApiLogger = LogManager.GetLogger("RequestApiPacketLogger");
      private static readonly ILog ResponseApiLogger = LogManager.GetLogger("ResponseApiPacketLogger");
  
      public LoggingMiddleware(AppFunc next)
      {
          _next = next;
      }
  
      public async Task Invoke(IDictionary&lt;string, object&gt; environment)
      {
          var correlationId = Guid.NewGuid();
          IOwinContext context = new OwinContext(environment);
  
          // Buffer the request (body is a string, we can use this to log the request later
          var requestBody = new StreamReader(context.Request.Body).ReadToEnd();
          var requestData = Encoding.UTF8.GetBytes(requestBody);
          context.Request.Body = new MemoryStream(requestData);
  
          // Buffer the response
          var responseBuffer = new MemoryStream();
          var responseStream = context.Response.Body;
          context.Response.Body = responseBuffer;
  
          // add the "http-tracking-id" response header so the user can correlate back to this entry
          var responseHeaders = (IDictionary&lt;string, string[]&gt;)environment["owin.ResponseHeaders"];
          responseHeaders["http-tracking-id"] = new[] { correlationId.ToString("d") };
  
          IDictionary&lt;string, string[]&gt; responseHeadersClone = new Dictionary&lt;string, string[]&gt;(responseHeaders);
  
          //invoke the next piece of middleware in the pipeline
          await _next.Invoke(environment);
  
          // rewind the request and response buffers and record their content
          responseBuffer.Seek(0, SeekOrigin.Begin);
          var reader = new StreamReader(responseBuffer);
          var responseBody = await reader.ReadToEndAsync();
  
          // log the request/response as long at it wasn't preflight
          if (context.Request.Method.ToUpper() != "OPTIONS")
          {
              RequestApiLogger.LogHttpRequestAsync(context, correlationId, requestBody);
              ResponseApiLogger.LogHttpResponseAsync(context, correlationId, responseBody, responseHeadersClone);
          }
  
          // You need to do this so that the response we buffered is flushed out to the client application.
          responseBuffer.Seek(0, SeekOrigin.Begin);
          await responseBuffer.CopyToAsync(responseStream);
      }
  }
  </code></pre>