Home > Mobile >  C# Core MVC How to apply custom URL to controller action
C# Core MVC How to apply custom URL to controller action

Time:10-26

Question:

Edit: It seems my question is actually not a routing issue but an anchoring issue.

If I have assigned a route:

[Route("~/Envelope/List/AcademicYear/{year}")] 
public IActionResult AcademicYear(string year)
{
}

How would I correctly use an asp-action to call this route? using

<a asp-action="List/AcademicYear/" asp-route-id="@Model.AcademicYear">@Model.AcademicYear</a>

returns a url with a / (Envelopes/List/AcademicYear/2122) instead of / (Envelopes/List/AcademicYear/2122) and thus results in a 404 error

How do I use Custom URL with asp-action to call a specific Action in my Controller?

or

How do I change the routing so I can call an action from a controller with a non default route mapping?

Context:

I've read https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-5.0 and yet i'm still confused on the whole concept of routing and how to interacts with controllers and actions.

In my application I have a controller called Envelope - it controls everything to do with my Envelopes.

I have a class in the Envelopes controller called

public class EnvelopeController : Controller {

 public IActionResult List() {... return View()}

and it returns the List.cshtml view. The current url as set by default route mapping: /Envelope/List

In the List.cshtml I have a link that is intended to filter the List on a year parameter

<a asp-action="AcademicYear" asp-route-academicYear="@Model.AcademicYear"> @Model.AcademicYear</a>

My intention is to pass this into a method in the Envelopes controller called "AcademicYear" that gathers the Envelope data stored in temp data, deseralises it and then returns a filtered version based on the parameter:

public IActionResult AcademicYear(string academicYear) { return View("List", newViewModel)}

The return url after this point is correctly: /Envelope/AcademicYear?academicYear=21/22

However I would Like to know how to change this so even though I call the Action

<a asp-action="AcademicYear" asp-route-academicYear="@Model.AcademicYear"/>

the URL returned would look like this /Envelope/List/AcademicYear/2122/

Is there a way of doing this? Am I looking at the problem the wrong way? I have thought about simply passing a parameter in the List action and running some form of control to do either set of operations depending on the parameters existence but realistically the List method and the filtering AcademicYear method aren't really doing the same thing and I'd like to seperate out the code into different methods if possible.

Even if its not the appropriate solution I would still like to know if it is possible to change the URL routing for an action after it has been called.

Edit : I have tried using HttpGet(List/AcademicYear/{academicYear:[a-zA-Z]} however when I do this I can't actually call List/AcademicYear as an asp-action due to the "/" and how that encodes to /

Answer:

With the help of the below solutions I realised I was looking at the problem wrong and was actually having issues creating correct anchors.

Reading: https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-5.0#url-generation-and-ambient-values-1

I realised the answer was staring me in the face and I used this alongside the Routes provided for in the answers

<a id="@academicYear.Name" href="@Url.Action("AcademicYear", "Envelope",new {year= academicYear.Name})">

CodePudding user response:

Maybe you just need to decorate your action like that:

[HttpGet("List/AcademicYear/{year:int}")] // or HttpPost it depends on you
public IActionResult AcademicYear(string year) { }

CodePudding user response:

You can add several attribute routes to the action.

[Route("~/Envelope/List/AcademicYear/{year}", Name="ListRoute")]
[Route("~/Envelope/AcademicYear/{year}")] 
public IActionResult AcademicYear(string year) { }

and if you need this url

http://localhost:xxxx/Envelope/List/AcademicYear/2021

you can use this html helper, that will create a right anchor tag for you using an attribute route name.

@Html.RouteLink(@Model.AcademicYear, "ListRoute", new { year = @Model.AcademicYear })

I added Name="ListRoute" to the attribute routing (see above)

  • Related