gpt4 book ai didi

.net-core - 更改.Net Core 3.1中的请求路径

转载 作者:行者123 更新时间:2023-12-03 16:11:59 25 4
gpt4 key购买 nike

在3.0之前的版本中,只需访问HttpRequestHttpContext属性,然后更改Path的值,就可以更改请求的路径(不使用任何形式的浏览器重定向)。

例如,为了显示需要更改密码的用户的页面(与用户打算访问的页面无关),我扩展了 HttpContext

public static void ChangeDefaultPassword(this HttpContext context) 
=> context.Request.Path = "/Account/ChangePassword";

这段代码将用户带到 ChangePassword中的操作方法 AccountController,而无需执行用户打算访问的操作方法。

然后进入dotnet core 3.1。

在3.1中,扩展方法更改路径。但是,它从不执行action方法。它 忽略更新路径。

我知道这是由于路由中的更改引起的。现在可以使用扩展方法 HttpContext.GetEndpoint()访问端点。还有一个扩展方法 HttpContext.SetEndpoint,它似乎是设置新端点的正确方法。但是,没有有关如何完成此操作的示例。

问题

如何在不执行原始路径的情况下更改请求路径?

我尝试过的内容
  • 我尝试更改路径。似乎在dotnet core 3.1中的路由会忽略HttpRequest路径值的值。
  • 我尝试使用context.Response.Redirect("/Account/ChangePassword");重定向。这行得通,但首先执行了用户请求的原始操作方法。这种行为违背了目的。
  • 我尝试使用扩展方法HttpContext.SetEndpoint,但是没有可用的示例。
  • 最佳答案

    我能够找到一个可行的解决方案。我的解决方案通过使用SetEndpoint扩展方法手动设置新端点来工作。

    这是我为解决此问题而创建的扩展方法。

        private static void RedirectToPath(this HttpContext context, string controllerName, string actionName )
    {
    // Get the old endpoint to extract the RequestDelegate
    var currentEndpoint = context.GetEndpoint();

    // Get access to the action descriptor collection
    var actionDescriptorsProvider =
    context.RequestServices.GetRequiredService<IActionDescriptorCollectionProvider>();

    // Get the controller aqction with the action name and the controller name.
    // You should be redirecting to a GET action method anyways. Anyone can provide a better way of achieving this.
    var controllerActionDescriptor = 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.Contains(HttpMethods.Get)))))
    .Select(s => s as ControllerActionDescriptor)
    .FirstOrDefault();

    if (controllerActionDescriptor is null) throw new Exception($"You were supposed to be redirected to {actionName} but the action descriptor could not be found.");

    // Create a new route endpoint
    // The route pattern is not needed but MUST be present.
    var routeEndpoint = new RouteEndpoint(currentEndpoint.RequestDelegate, RoutePatternFactory.Parse(""), 1, new EndpointMetadataCollection(new object[] { controllerActionDescriptor }), controllerActionDescriptor.DisplayName);

    // set the new endpoint. You are assured that the previous endpoint will never execute.
    context.SetEndpoint(routeEndpoint);
    }

    重要
  • 您必须通过将操作方法​​放在“共享”文件夹中来使其可用。或者,您可以决定提供IViewLocationExpander的自定义实现
  • 在访问端点之前,必须已执行路由中间件。

  • 用法
    public static void ChangeDefaultPassword(this HttpContext context) 
    => context.RedirectToPath("Account","ChangePassword");

    关于.net-core - 更改.Net Core 3.1中的请求路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60065745/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com