修改后的请求路径上的 HttpContext GetEndpoint .net 5
HttpContext GetEndpoint on modified request path .net 5
我正在尝试创建一个中间件来处理 url 中的国家/地区代码。
我的代码非常适合删除国家代码,因此它被路由到 mvc 管道中的正确端点。
我遇到的问题是我需要根据端点是否具有特定属性来执行一些操作。
我看到 HttpContext
有一个方法 GetEndpoint
,这正是我需要的。
当国家代码在url(mysite.com/us/home/Index)时,
GetEndpoint
returns 空。
但是如果我在 url (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);
}
我找到了解决方法,
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>();
我不知道它的扩展性如何,但它现在可以使用。
我在这里找到了代码的主要部分:
我遇到了同样的问题,问题的解决方案(至少是我的)是 Startup 中中间件的顺序:您的自定义中间件必须在 UseRouting()
之后
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseRouting();
app.UseMiddleware<MyCustomMiddleware>();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}
我正在尝试创建一个中间件来处理 url 中的国家/地区代码。 我的代码非常适合删除国家代码,因此它被路由到 mvc 管道中的正确端点。
我遇到的问题是我需要根据端点是否具有特定属性来执行一些操作。
我看到 HttpContext
有一个方法 GetEndpoint
,这正是我需要的。
当国家代码在url(mysite.com/us/home/Index)时,
GetEndpoint
returns 空。
但是如果我在 url (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);
}
我找到了解决方法,
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>();
我不知道它的扩展性如何,但它现在可以使用。
我在这里找到了代码的主要部分:
我遇到了同样的问题,问题的解决方案(至少是我的)是 Startup 中中间件的顺序:您的自定义中间件必须在 UseRouting()
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseRouting();
app.UseMiddleware<MyCustomMiddleware>();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}