【问题标题】:HttpContext GetEndpoint on modified request path .net 5HttpContext GetEndpoint 修改请求路径.net 5
【发布时间】:2021-05-19 08:43:48
【问题描述】:

我正在尝试创建一个中间件来处理网址中的国家/地区代码。 我的代码非常适合删除国家代码,因此它被路由到 mvc 管道中的正确端点。

我遇到的问题是我需要根据端点是否具有某个属性来执行一些操作。

我看到HttpContext 有一个方法GetEndpoint,这正是我需要的。

当 countryCode 在 url (mysite.com/us/home/Index) 中时, GetEndpoint 返回 null。

但如果我在网址 (mysite.com/home/Index) 中输入没有国家代码的网站,则 GetEndpoint 有效。

如何在修改后的请求 url 上使用GetEndpoint() 方法?

HttpContext 上的另一个属性我需要更改吗?

public async Task InvokeAsync(HttpContext httpContext)
{
    // mysite.com/us/home/Index
    var currentAddress = httpContext.Request.Path; 
    
    // mysite.com/home/Index
    httpContext.Request.Path = ExtractCountryCodeFromUrl(currentAddress); 

    var endpoint = httpContext.GetEndpoint(); // null

    var hasMyAttribute = endPoint.Metadata.GetMetadata<MyAttribute>();
    // Do something...

    await next(httpContext);
}

【问题讨论】:

  • 用Request.GetDisplayUrl();怎么样?

标签: c# asp.net-core model-view-controller middleware .net-5


【解决方案1】:

我找到了解决办法,

private static ControllerActionDescriptor GetControllerByUrl(HttpContext httpContext)
{
    var pathElements = httpContext.Request.Path.ToString().Split("/").Where(m => m != "");
    string controllerName = (pathElements.ElementAtOrDefault(0) == "" ? null : pathElements.ElementAtOrDefault(0)) ?? "w";
    string actionName = (pathElements.ElementAtOrDefault(1) == "" ? null : pathElements.ElementAtOrDefault(1)) ?? "Index";

    var actionDescriptorsProvider = httpContext.RequestServices.GetRequiredService<IActionDescriptorCollectionProvider>();
    ControllerActionDescriptor controller = actionDescriptorsProvider.ActionDescriptors.Items
    .Where(s => s is ControllerActionDescriptor bb
                && bb.ActionName == actionName
                && bb.ControllerName == controllerName
                && (bb.ActionConstraints == null
                    || (bb.ActionConstraints != null
                        && bb.ActionConstraints.Any(x => x is HttpMethodActionConstraint cc
                        && cc.HttpMethods.Any(m => m.ToLower() == httpContext.Request.Method.ToLower())))))
    .Select(s => s as ControllerActionDescriptor)
    .FirstOrDefault();
    return controller;
}

那我就可以了

ControllerActionDescriptor controller = GetControllerByUrl(httpContext);
var countryCodeAttribute = controller.MethodInfo.GetCustomAttribute<MyAttribute>();

我不知道它的扩展性如何,但它现在可以工作。 我在这里找到了代码的主要部分:Changing Request Path in .Net Core 3.1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-20
    • 2018-04-17
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多