3

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 %2f (Envelopes/List%2fAcademicYear/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://learn.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%2F22

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 %2f

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://learn.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})">
2
  • I`m not sure i understand you: do you whant to have allways url /Envelope/List or after filtering you whant to have url /Envelope/AcademicYear/2122 Commented Oct 25, 2021 at 11:35
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. Commented Oct 25, 2021 at 11:49

3 Answers 3

2

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) { }
Sign up to request clarification or add additional context in comments.

1 Comment

This was my first approach as I thought thats how it worked. However it seems to be the reverse of that. The decoration of the action changes the action you call in your cshtml file. Using: <a asp-action="AcademicYear"></a> no longer will work and <a asp-action="List/AcademicYear"></a> returned "Envelope/List%2f%AcademicYear"
1

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)

8 Comments

Sorry I can't upvote this because I've just created a stackoverflow account. This is very helpful and has worked a treat. However now I can type the specific URLs and have them show me the same things, how would i use the asp-action anchor to allow me to pass asp-action="List/AcademicYear" -- If i use asp-action="AcademicYear" it will route to ~/Envelope/AcademicYear/2122 and not ~/Envelope/List/AcademicYear/2122
@LewDavis I added this action to the routes. ~/Envelope/AcademicYear/2122 will work. I don't know what do you need ? What url is not working?
I'm sorry i'm not explaining this well and its terrible to show in the comment. The only route I want is Envelope/List/AcademicYear/{year} - I understand I can add and remove route attributes to change this. However I am unaware how to correctly send a request to the server for the route "Envelope/List/AcademicYear/" if i use the asp-action anchor <a asp-action="List/AcademicYear"></a> a "%2f" is passed in place of the "\" and I get a 404 error. If i use <a asp-action="AcademicYear"></a> with your routes it simply routes to "Envelopes/AcademicYear/2122" which is not what I intend for.
You should explain in your question that you don't know how to make a right ancor. Since everybody thinks that you have a right ancor, but you just need to add the route.
My bad I thought this section explained that: 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/
|
0

For me it worked like this:

 [HttpGet("GetById/{id}")]
 public async Task<ActionResult<Message>> GetMessageById(int id)
 {

calling from react with axios:

 const response = await axiosInstance.get(`/messages/GetById/${id}`);
        const message = response.data;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.