web api从内部处理程序获取路由模板 [英] web api get route template from inside handler

查看:23
本文介绍了web api从内部处理程序获取路由模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在提出问题之前我搜索了很多,但我搜索得越多,我就越困惑.

I searched a lot before putting the questions here but the more I search the more confused I get.

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

So I have created an handler and I am trying to get the route like this:

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

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

GetRouteData returns null so I can't get to the RouteTemplate property but I can see the route there in a list deep in the stack. I found so many different ways which one can use to get the route, but those methods evaluate to null as well. I am a bit lost on how to get something so simple done. I am using self host for development but will use IIS for deployment.

更新 1

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

I forgot to put here what else I had tried:

//NULL
request.GetRouteData(); 
//EMPTY
request.GetRequestContext().Configuration.Routes.GetRouteData(request).Route.RouteTemplate;
//EMPTY
request.GetConfiguration().Routes.GetRouteData(request).Route.RouteTemplate;

路由工作得很好,但奇怪的是,如果我尝试让控制器为该请求提供服务,我会收到 404...

The route works just fine, but strangely if I try to get the controller to service that request I get a 404... if I just step over that I will get to the controller just fine.

HttpControllerDescriptor httpControllerDescriptor = request.GetRequestContext().Configuration.Services.GetHttpControllerSelector().SelectController(request);
IHttpController httpController = httpControllerDescriptor.CreateController(request);

我正在使用 autofac 来发现我定义的所有路由,就像:

I am using autofac to discover all the routes which I am defining just like:

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

更新 2

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

If I GetRouteData gets called after the line above, I am able to get the route template:

base.SendAsync(request, cancellationToken);

var routeData = request.GetRouteData();

所以也许我误解了整个画面,在解析为请求执行哪个控制器的处理程序开始工作之前我无法获得路由模板......是这种情况吗?

So maybe I misunderstood the whole picture and I cant get the route template before the handler that resolves which controller to execute for the request does its work... is that the case?

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

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

更新 3

代码在非自托管环境中运行良好,所以这更像是自托管问题.

The code runs fine in a non self hosting environment, so this is more like a self host issue.

推荐答案

Web Api 仍有很多需要改进的地方.找到一种方法来让这个工作很棘手,我只是希望这可以让其他人免于花我所做的所有时间.

The Web Api still has a lot to improve. It was tricky to find a way to get this working and I just hope this saves other guys from spending all the time I did.

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

这篇关于web api从内部处理程序获取路由模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆