Web Api 2 получает контроллер и имя действия в промежуточном программном обеспечении OWIN?

Как я могу получить имя контроллера API и имя действия API внутри части пользовательского промежуточного программного обеспечения OWIN? Я могу сделать это внутри обработчика сообщений следующим образом:

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. Как я могу получить имя контроллера и имя действия в этом коде?

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);
    }
}

person BBauer42    schedule 22.02.2016    source источник


Ответы (1)


Вы действительно не можете. ПО промежуточного слоя OWIN не знает о Web Api. Он знает только об окружающей среде, которая передается ему. Идея промежуточного программного обеспечения заключается в том, что оно не зависит от платформы хостинга и приложений.

Вы не привели конкретного примера того, чего вы пытаетесь достичь, поэтому может быть способ сделать то, что вы пытаетесь сделать.

Обновление, включающее ответ на заявление выше:

Вы можете отменить то, что вы пытаетесь сделать. Вроде. Среда OWIN доступна в HttpRequest внутри Web Api с помощью метода GetOwinEnvironmentExtension. Вы можете добавить переменную среды в словарь с именем контроллера и метода внутри контроллера, а затем использовать ее, когда ваше промежуточное ПО вызывается после завершения веб-API. Много повторяющегося кода, но это сработает.

Вероятно, есть способ перехватить метод до его вызова. Ознакомьтесь с этим ответом @mark-jones, который может дать вам некоторое представление о том, как это сделать.

Надеюсь, это поможет.

person MichaelDotKnox    schedule 25.02.2016
comment
Я обновил свой вопрос, чтобы показать свою текущую часть промежуточного программного обеспечения для ведения журнала. Я пытаюсь получить ControllerName и ActionName, чтобы включить эти поля в свою таблицу журналов для лучшей отслеживаемости. - person BBauer42; 25.02.2016