如何在一个自定义OWIN中间件中检索api控制器名称和api操作名称?我可以在消息处理程序中执行此操作:
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
更新 这是我目前的OWIN中间件。如何在此代码中获取controllerName和actionName?
using AppFunc = Func<IDictionary<string, object>, Task>;
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<string, object> 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<string, string[]>)environment["owin.ResponseHeaders"];
responseHeaders["http-tracking-id"] = new[] { correlationId.ToString("d") };
IDictionary<string, string[]> responseHeadersClone = new Dictionary<string, string[]>(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);
}
}
答案 0 :(得分:2)
你真的不能。 OWIN中间件不了解Web Api。它只知道传递给它的环境。中间件的概念是它独立于托管和应用程序平台。
您没有提供您要完成的具体示例,因此可能有一种方法可以执行您要执行的操作。
更新以包含对上述声明的回复:
您可以撤消您要执行的操作。均田。使用GetOwinEnvironmentExtension方法在Web Api内的HttpRequest上可以使用OWIN环境。您可以使用控制器内部的控制器和方法的名称向字典添加环境变量,然后在web api完成后调用中间件时使用该变量。很多重复的代码,但它会工作。
在调用方法之前,可能有一种拦截方法的方法。查看来自@ mark-jones的this回答,可能会让您对此有所了解。
希望有所帮助。