Anduin Xue
Anduin Xue

Reputation: 3737

Infinite path route into an ASP.NET Core action

I want create a route which routes an infinite collection of strings in url.

Like this:

https://github.com/{orgName}/{projectName}/blob/{branchName}/{folderName1}/{folderName2}/.../{folderNameN}/{fileName}

For eample

https://github.com/AiursoftWeb/Nexus/blob/master/Account/Controllers/AccountController.cs

Will be routed to this action. And route result shall be:

orgName: AiursoftWeb
projectName: Nexus
branchName: master
folderNames: string[2] of:
    "Account"
    "Controllers"
fileName: AccountController.cs

How do I achieve that?

I have tried the following way:

[Route("Folders/ViewContent/{siteName}/{folderNames}")]
public async Task<IActionResult> ViewContent(string siteName, params string[] folderNames)
{
    throw new NotImplementedException();
}

But it doesn't work.

Upvotes: 5

Views: 2786

Answers (2)

NineBerry
NineBerry

Reputation: 28499

Use the asterisk character to denote a placeholder in the route template as a catch-all parameter. You do then have to split this parameter into folder names yourself:

[Route("Folders/ViewContent/{siteName}/{*folderNames}")]
public async Task<IActionResult> ViewContent(string siteName, string folderNames)
{
    folderNames = folderNames ?? "";
    string[] folders = folderNames.Split('/', StringSplitOptions.RemoveEmptyEntries);

     // your other code
}

Starting with ASP.net Core 2.2 you should use double asterisk so that urls generated automatically will not url-escape the slashes in the url:

[Route("Folders/ViewContent/{siteName}/{**folderNames}")]

From https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-2.2

You can use an asterisk (*) or double asterisk (**) as a prefix to a route parameter to bind to the rest of the URI. These are called a catch-all parameters. For example, blog/{**slug} matches any URI that starts with /blog and has any value following it, which is assigned to the slug route value. Catch-all parameters can also match the empty string.

The catch-all parameter escapes the appropriate characters when the route is used to generate a URL, including path separator (/) characters. For example, the route foo/{*path} with route values { path = "my/path" } generates foo/my%2Fpath. Note the escaped forward slash. To round-trip path separator characters, use the ** route parameter prefix. The route foo/{**path} with { path = "my/path" } generates foo/my/path.

Upvotes: 13

Anirudha Gupta
Anirudha Gupta

Reputation: 9289

You are using 2 constraint in your routing which lead to exactly match from the URL. Are you sure your url start with "Folders/ViewContent/". You have 6 folder name in your URL according your question but your routing only handle 4 folder that deeeper. Write the routing to match that folder by passing more foldername (or placeholder for folder).

For better debugging you can pass the whole url as static and change one by one to better debug your routing.

Upvotes: 0

Related Questions