c# - 获取不同 HttpContext 的端点

标签 c# asp.net-core

我正在尝试编写一个 Controller 操作,它将获取给定 URL 的元数据(特别是要传递的参数)。类似的问题还有很多,如Asp.Net core get RouteData value from url ,但从 ASP.NET Core 3.1 开始,这些似乎不正确,因为它已切换到“端点路由”。

因此,像 var router = RouteData.Routers.First(); //get the top level router 这样的代码将不再正常工作,如 Routers没有充满任何有意义的东西。

我看到了一些为当前 HttpContext 使用端点的示例,例如 here ,但没有自定义的。

我还看到提到 IActionDescriptorCollectionProvider ,但这不会让我轻松过滤特定的 URL。

到目前为止,我正在注入(inject)一个 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>());
    }

这可以让我得到正确的类型,但不是正确的结果。
EndpointFeature 没有公共(public)构造函数,所以我可能不应该通过我自己的。上面的代码采用 IEndpointFeature来自原始(“错误”)http上下文,因此会给我一个GetRouteDataForUrl的端点 Controller ,而不是我在 URL 中传递的 Controller 。

最佳答案

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

我最终使用的两个关键部分是 EndpointDataSourceLinkParser :

private readonly EndpointDataSource _EndpointDataSource;
private readonly LinkParser _LinkParser;

public MyController(EndpointDataSource endpointDataSource, LinkParser linkParser)
{
   _EndpointDataSource = endpointDataSource;
   _LinkParser = linkParser;
}

我可以使用端点数据源遍历所有端点,并使用链接解析器将端点与 expectedUri 进行匹配。 (这是用户传递的 URL):

[HttpGet]
public IActionResult GetActionMetadata(Uri forUri)
{
    foreach (var endpoint in this._EndpointDataSource.Endpoints)
    {
        if (!TryGetEndpointMetadata(endpoint, out var name, out var controllerActionDescriptor))
            continue;

        // we only use this to match the endpoint to the URL
        var dict = _LinkParser.ParsePathByEndpointName(name, expectedUri.AbsolutePath);
        if (dict == null)
            continue;

        // if we get here, it's the endpoint we're looking for, and we can proceed with your actual parsing

         /* actually do things with the endpoint */
    }
}

关于c# - 获取不同 HttpContext 的端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59561114/

相关文章:

c# - CancellationToken 在 asp.net core 中不起作用

Docker 多个相同端口问题

c# - c# 中的字符串相等运算符 ==

C# 更新 mySQLDateTime 数据表

c# - 反转表达式<Func<T, bool>>

asp.net-core - 设置.NET Core项目的版本号

c# - 将 IsAssignableFrom 与 'open' 泛型类型一起使用

c# - 在后台写入文件

security - 如何在 asp.net core(本地)中保护 ConnectionString 和/或 AppSettings

asp.net-core - 返回404页面,无需重定向