C# 获取不同HttpContext的端点

C# 获取不同HttpContext的端点,c#,asp.net-core,C#,Asp.net Core,我正在尝试编写一个控制器操作,它将为给定的URL获取元数据(特别是要传递的参数)。有许多类似的问题,例如,但这些问题在ASP.NET Core 3.1中似乎并不正确,因为它已切换到“端点路由” 因此,代码类似于var router=RouteData.Routers.First()//获取顶级路由器将不再正常工作,因为路由器中没有任何有意义的内容 我看到了一些在当前HttpContext中使用端点的示例,例如,但没有一个用于自定义端点 我还提到了IActionDescriptorCollecti

我正在尝试编写一个控制器操作,它将为给定的URL获取元数据(特别是要传递的参数)。有许多类似的问题,例如,但这些问题在ASP.NET Core 3.1中似乎并不正确,因为它已切换到“端点路由”

因此,代码类似于
var router=RouteData.Routers.First()//获取顶级路由器
将不再正常工作,因为
路由器
中没有任何有意义的内容

我看到了一些在当前HttpContext中使用端点的示例,例如,但没有一个用于自定义端点

我还提到了
IActionDescriptorCollectionProvider
,但这并不能让我轻松地筛选特定的URL

到目前为止,我正在注入一个HttpContextFactory,但是从当前上下文向它传递
IEndpointFeature

    private readonly IHttpContextFactory _HttpContextFactory;

    public MyController(IHttpContextFact httpContextFactory)
    {
        _HttpContextFactory = httpContextFactory;
    }

    public async Task<ActionResult> GetRouteDataForUrl([FromQuery(Name = "url")] string url)
    {
        var uri = new Uri(url);

        // this is probably wrong -- it supplies the _original_ context's endpoint feature
        var featureCollection = this.HttpContext.Features;

        var httpContext = _HttpContextFactory.Create(featureCollection);
        httpContext.Request.Path = uri.PathAndQuery;

        var feature = httpContext.Features.Get<IEndpointFeature>();
        var endpoint = httpContext.Features.Get<IEndpointFeature>()?.Endpoint; // see https://github.com/aspnet/AspNetCore/issues/5135#issuecomment-461547335

        return Ok(endpoint.Metadata.OfType<Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor>());
    }
私有只读IHttpContextFactory\u HttpContextFactory;
公共MyController(IHttpContextFact httpContextFactory)
{
_HttpContextFactory=HttpContextFactory;
}
公共异步任务GetRouteDataForUrl([FromQuery(Name=“url”)]字符串url)
{
var uri=新的uri(url);
//这可能是错误的——它提供了original_uu上下文的端点特性
var featureCollection=this.HttpContext.Features;
var httpContext=_HttpContextFactory.Create(featureCollection);
httpContext.Request.Path=uri.PathAndQuery;
var feature=httpContext.Features.Get();
var endpoint=httpContext.Features.Get()?.endpoint;//请参见https://github.com/aspnet/AspNetCore/issues/5135#issuecomment-461547335
返回Ok(endpoint.Metadata.OfType());
}
这可以让我得到正确的类型,但不能得到正确的结果

EndpointFeature
没有公共构造函数,所以我可能不应该通过自己的构造函数。上面的代码从原始的(“错误的”)http上下文中获取了
IEndpointFeature
,因此将为
GetRouteDataForUrl
控制器提供一个端点,而不是我在URL中传递的控制器。

我最终解决了这个问题(尽管我不确定我是否以最干净或最有效的方式这样做)

我最后使用的两个关键部分是
EndpointDataSource
LinkParser

私有只读EndpointDataSource\u EndpointDataSource;
专用只读链接解析器_LinkParser;
公共MyController(EndpointDataSource EndpointDataSource、LinkParser LinkParser)
{
_EndpointDataSource=EndpointDataSource;
_LinkParser=LinkParser;
}
我可以使用端点数据源迭代所有端点,并使用链接解析器将端点与
expectedUri
(用户传递的URL)匹配:

[HttpGet]
公共IActionResult GetActionMetadata(Uri forUri)
{
foreach(此.u EndpointDataSource.Endpoints中的var端点)
{
if(!TryGetEndpointMetadata(端点、out var名称、out var controllerActionDescriptor))
继续;
//我们只使用它来匹配端点和URL
var dict=_LinkParser.ParsePathByEndpointName(名称,expectedUri.AbsolutePath);
if(dict==null)
继续;
//如果我们到达这里,它就是我们正在寻找的端点,我们可以继续进行实际的解析
/*实际使用端点执行操作*/
}
}

看看是的,谢谢
EndpointDataSource
也是我最终解决它的一部分。