【问题标题】:Web Api 2 get controller and action name in OWIN middleware?Web Api 2 在 OWIN 中间件中获取控制器和操作名称?
【发布时间】:2016-06-04 08:00:32
【问题描述】:

如何在自定义 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);
    }
}

【问题讨论】:

    标签: c# asp.net-web-api owin owin-middleware


    【解决方案1】:

    你真的不能。 OWIN 中间件不知道 Web Api。它只知道传递给它的环境。中间件的理念是独立于托管和应用平台。

    您没有提供您想要完成的具体示例,因此可能有一种方法可以做您正在尝试做的事情。

    更新以包括对上述声明的回应:

    你可以扭转你正在尝试做的事情。有点。 OWIN 环境可通过 GetOwinEnvironmentExtension 方法在 Web Api 内部的 HttpRequest 上使用。您可以使用控制器名称和控制器内部的方法将环境变量添加到字典中,然后在 web api 完成后调用中间件时使用它。很多重复的代码,但它会工作。

    可能有一种方法可以在方法调用之前对其进行拦截。查看来自@mark-jones 的this 答案,这可能会让您对此有所了解。

    希望对您有所帮助。

    【讨论】:

    • 我更新了我的问题以显示我当前的日志中间件。我正在尝试获取 ControllerName 和 ActionName,以便我可以将这些字段包含在我的日志记录表中以获得更好的可追溯性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    相关资源
    最近更新 更多