Changing Request Path in .Net Core 3.1

Shittu Joseph Olugbenga

Prior to 3.0, I could change the path of a request (without any form of browser redirection) by just accessing the HttpRequest property of the HttpContext and then changed the value of the Path.

As an example, to display a page for a user who needed to change his/her password (irrespective of the page the user intended to visit), I extended the HttpContext

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

This piece of code takes the user to the action method ChangePassword in the AccountController without executing the action method the user intends to visit.

Then enters dotnet core 3.1.

In 3.1, the extension method changes the path. However, it never executes the action method. It ignores the updated path.

I am aware this is due to the changes in the routing.The endpoint can now be accessed with the extension method HttpContext.GetEndpoint(). There is also an extension method HttpContext.SetEndpoint which seems to be the right way to set a new endpoint. However, there is no sample of how to accomplish this.

The Question

How do I change the request path, without executing the original path?

What I Have Tried

  1. I tried changing the path. It seems routing in dotnet core 3.1 ignores the value of the HttpRequest path value.
  2. I tried redirecting with context.Response.Redirect("/Account/ChangePassword");. This worked but it first executed the original action method requested by the user. This behavior defeated the purpose.
  3. I tried using the extension method HttpContext.SetEndpoint, but there was no example available to work with.
Shittu Joseph Olugbenga

I was able to find a working solution. My solution works by manually setting a new endpoint with the SetEndpoint extension method.

Here is an extension method I created to resolve this issue.

    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);
    }

Important

  1. You must make the view of the action method available by placing it in the Shared folder. Alternatively, you may decide to provide a custom implementation of IViewLocationExpander
  2. Before accessing the endpoint, the routing middleware must have executed.

USAGE

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

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Log request payloads in .NET Core 3

分類Dev

Path to LocalAppData in ASP.Net Core application

分類Dev

.Net Core API Returning StreamContent with request object

分類Dev

Database Schema not changing at Runtime in Asp.net Core 2.2 & Entity Framework Core

分類Dev

Path based authentication in ASP.NET Core MVC 2.0

分類Dev

Generate dynamic route path in asp.net core

分類Dev

Unable to get request header in asp net core web API

分類Dev

get request.Body param value .net core 2

分類Dev

C# .net core, Log request without sensitive information

分類Dev

C#.net Core web Api Get request#parameter

分類Dev

EnableCors C#.NET Core 3

分類Dev

Path.GetDirectoryName() isn't returning ArgumentException for empty path in .net core

分類Dev

WPF Control Library Target .NET Core 3 or .NET Framework?

分類Dev

Changing a default request header for HttpClient

分類Dev

Changing ajax jquery request to a XMLHttpRequest

分類Dev

.NET Core 3 API-1回のリクエストで動作を停止しますか?

分類Dev

.NET Core 3 rc1から最終アップグレード:Visual Studio2019にありません

分類Dev

Building apps using .NET Core 2.0.0 Preview 1 on VSTS

分類Dev

how to integrate ASP.NET Core 2.1 with Vue CLI 3?

分類Dev

how to integrate ASP.NET Core 2.1 with Vue CLI 3?

分類Dev

Azure AppServiceとしてBlazorhostedASP.NET Core 3

分類Dev

Custom Role with .NET Core 3 Azure AD Authentication

分類Dev

Omnisharp not properly handling default dot net core 3 app in vscode

分類Dev

Asp Net Core 3 Sample with 503 Service Unavailable

分類Dev

.NET Core 3 - IIS - Application Initialization doesn't work

分類Dev

ASP.NET Core 3 No Sign-In Manager Is Registered for the Scheme

分類Dev

Using Function logic in LINQ Query net core 3

分類Dev

Spring RestTemplate 404 error for large POST request to .NET Core REST api

分類Dev

How can I replace Request.Url.GetLeftPart(UriPartial.Authority) for .NET Core View class?

Related 関連記事

  1. 1

    Log request payloads in .NET Core 3

  2. 2

    Path to LocalAppData in ASP.Net Core application

  3. 3

    .Net Core API Returning StreamContent with request object

  4. 4

    Database Schema not changing at Runtime in Asp.net Core 2.2 & Entity Framework Core

  5. 5

    Path based authentication in ASP.NET Core MVC 2.0

  6. 6

    Generate dynamic route path in asp.net core

  7. 7

    Unable to get request header in asp net core web API

  8. 8

    get request.Body param value .net core 2

  9. 9

    C# .net core, Log request without sensitive information

  10. 10

    C#.net Core web Api Get request#parameter

  11. 11

    EnableCors C#.NET Core 3

  12. 12

    Path.GetDirectoryName() isn't returning ArgumentException for empty path in .net core

  13. 13

    WPF Control Library Target .NET Core 3 or .NET Framework?

  14. 14

    Changing a default request header for HttpClient

  15. 15

    Changing ajax jquery request to a XMLHttpRequest

  16. 16

    .NET Core 3 API-1回のリクエストで動作を停止しますか?

  17. 17

    .NET Core 3 rc1から最終アップグレード:Visual Studio2019にありません

  18. 18

    Building apps using .NET Core 2.0.0 Preview 1 on VSTS

  19. 19

    how to integrate ASP.NET Core 2.1 with Vue CLI 3?

  20. 20

    how to integrate ASP.NET Core 2.1 with Vue CLI 3?

  21. 21

    Azure AppServiceとしてBlazorhostedASP.NET Core 3

  22. 22

    Custom Role with .NET Core 3 Azure AD Authentication

  23. 23

    Omnisharp not properly handling default dot net core 3 app in vscode

  24. 24

    Asp Net Core 3 Sample with 503 Service Unavailable

  25. 25

    .NET Core 3 - IIS - Application Initialization doesn't work

  26. 26

    ASP.NET Core 3 No Sign-In Manager Is Registered for the Scheme

  27. 27

    Using Function logic in LINQ Query net core 3

  28. 28

    Spring RestTemplate 404 error for large POST request to .NET Core REST api

  29. 29

    How can I replace Request.Url.GetLeftPart(UriPartial.Authority) for .NET Core View class?

ホットタグ

アーカイブ