web api从处理程序内部获取路径模板

MeT*_*tus 8 c#-4.0 asp.net-web-api asp.net-web-api-routing asp.net-web-api2

在把这些问题放在这里之前我搜索了很多但是我搜索的越多,我得到的就越混乱.

所以我创建了一个处理程序,我试图得到这样的路线:

public class ExecutionDelegatingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (securityAuthority.VerifyPermissionToExecute(request.GetRouteData().Route.RouteTemplate, request.Headers))
        {
            return base.SendAsync(request, cancellationToken);
        }
        else
        {
            httpResponseMessage.StatusCode = HttpStatusCode.Unauthorized;
        }
    }
 }
Run Code Online (Sandbox Code Playgroud)

GetRouteData返回null,因此我无法访问RouteTemplate属性,但我可以在堆栈深处的列表中看到该路径.我找到了许多可以用来获取路径的不同方法,但这些方法也评估为null.我对如何完成如此简单的事情感到有点迷茫.我使用自主机进行开发,但将使用IIS进行部署.

更新1

我忘了把我尝试过的其他东西放在这里:

//NULL
request.GetRouteData(); 
//EMPTY
request.GetRequestContext().Configuration.Routes.GetRouteData(request).Route.RouteTemplate;
//EMPTY
request.GetConfiguration().Routes.GetRouteData(request).Route.RouteTemplate;
Run Code Online (Sandbox Code Playgroud)

路线工作得很好,但奇怪的是,如果我试图让控制器为这个请求提供服务,我会得到一个404 ......如果我只是跳过那个我就会到达控制器就好了.

HttpControllerDescriptor httpControllerDescriptor = request.GetRequestContext().Configuration.Services.GetHttpControllerSelector().SelectController(request);
IHttpController httpController = httpControllerDescriptor.CreateController(request);
Run Code Online (Sandbox Code Playgroud)

我正在使用autofac来发现我定义的所有路径,如:

[Route("queries/organization/clients")]
[HttpGet]
public ClientInitialScreenModel GetClients()
{
    return OrganizationModelsBuilder.GetClientInitialScreen();
}
Run Code Online (Sandbox Code Playgroud)

更新2

如果我在上面的行之后调用GetRouteData,我就可以获得路径模板:

base.SendAsync(request, cancellationToken);

var routeData = request.GetRouteData();
Run Code Online (Sandbox Code Playgroud)

所以也许我误解了整个图片,我无法在处理程序之前得到路由模板,该处理程序解析了为请求执行哪个控制器的工作......就是这样的情况?

作为参考,这是我正在处理的处理程序:

public class ExecutionDelegatingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var securityAuthority = (ISecurityAuthority) request.GetDependencyScope().GetService(typeof (ISecurityAuthority));
        var configuration = (IWebApiConfiguration)request.GetDependencyScope().GetService(typeof(IWebApiConfiguration));
        var tsc = new TaskCompletionSource<HttpResponseMessage>();
        var httpResponseMessage = new HttpResponseMessage();

        if (request.RequestUri.AbsolutePath.Equals(configuration.CommandGatewayUrl, StringComparison.InvariantCultureIgnoreCase))
        {
            var apiMessage = JsonConvert.DeserializeObject<ApiCommandEnvelope>(request.Content.ReadAsStringAsync().Result);

            if (securityAuthority != null && !securityAuthority.VerifyPermissionToExecute(apiMessage, request.Headers))
            {
                httpResponseMessage.StatusCode = HttpStatusCode.Unauthorized;
            }
            else
            {
                var messageProcessor = (IWebApiMessageProcessor)request.GetDependencyScope().GetService(typeof(IWebApiMessageProcessor));
                var reponse = messageProcessor.HandleRequest(apiMessage);

                httpResponseMessage.StatusCode = (HttpStatusCode) reponse.StatusCode;

                if (!string.IsNullOrEmpty(reponse.Content))
                {
                    httpResponseMessage.Content = new StringContent(reponse.Content);
                }
            }
        }
        else
        {
            if (securityAuthority != null && !securityAuthority.VerifyPermissionToExecute(request.GetRouteData().Route.RouteTemplate, request.Headers))
            {
                httpResponseMessage.StatusCode = HttpStatusCode.Unauthorized;
            }
            else
            {
                return base.SendAsync(request, cancellationToken);
            }
        }

        tsc.SetResult(httpResponseMessage);

        return tsc.Task;
    }
Run Code Online (Sandbox Code Playgroud)

更新3

代码在非自托管环境中运行良好,因此这更像是自托管主机问题.

MeT*_*tus 15

Web Api仍有很多需要改进的地方.找到一种让这种方法发挥作用的方法很棘手,我只希望这可以节省其他人花的所有时间.

 var routeTemplate = ((IHttpRouteData[]) request.GetConfiguration().Routes.GetRouteData(request).Values["MS_SubRoutes"])
                                    .First().Route.RouteTemplate;
Run Code Online (Sandbox Code Playgroud)