georgebreje
georgebreje

Reputation: 23

How to use Url.Action to get to the controller and also generate the url

When using this button

<a onclick="location.href='@Url.Action("Update", "Book", new { id = @Model.Id })'"
               class="btn btn-primary">Edit</a>

The controller indeed hits the get method

[HttpGet]
[Route("{id}")]
public ActionResult Update(int id) {...}

But the Url is not anymore matching the route {controller}/{action}, it just shows the id like this

https://localhost:44345/1

Upvotes: 1

Views: 2607

Answers (3)

Sean McCafferty
Sean McCafferty

Reputation: 266

You are overriding the entire route when you use the [Route()] attribute on your endpoint, this is why the controller name portion is removed. I imagine the reason you have done this is due to a conflict with an existing GET action.

You appear to be using a GET request to update your entity. Instead use POST or PUT depending on the scenario (https://www.w3schools.com/tags/ref_httpmethods.asp) and update your HttpGet attribute accodingly.

[HttpPost]
// or
[HttpPut]

However, XHTML 1.x forms only support GET and POST as HTTP request methods. You can either use POST or you can see workaround here if you want to use PUT.

Also, ensure that you have a route attribute on your controller class that looks like this:

[Route("[controller]")]
public class BookController : ControllerBase

This will ensure that the controller portion of the route is included, so the format will be: .../{controllerName}/{id}

NOTE: If you want to stick with GET and have multiple requests of the same HTTP message type then you can route to the correct action by updating the [HttpGet] attribute rather than adding a [Route] attribute :

[HttpGet("update/{id}")]

This will give your url the following format .../{controllerName}/update/{id}

Upvotes: 2

Rena
Rena

Reputation: 36775

If you use Route attribute, it will override the route template.

So if you use ASP.NET Core MVC, you need use the route template like below:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
});

Your Controller should be:

public class BookController : Controller
{
    [HttpGet]
    public ActionResult Update(int id) {

        return View();
    }
}

Then the Url.Action should work as expected:https://localhost:44345/Book/Update/1

 <a onclick="location.href='@Url.Action("Update", "Book", new { id = @Model.Id })'"
           class="btn btn-primary">Edit</a>

If you use ASP.NET Core WebApi, controller should be like below:

[Route("[controller]/[action]")]
[ApiController]
public class BookController : ControllerBase
{

    [HttpGet]
    [Route("{id}")]
    public ActionResult Update(int id) => Ok();
}

Upvotes: 0

Serge
Serge

Reputation: 43969

you can use an ancor helper

<a asp-action="Update" asp-controller="Book" asp-route-id="@Model.Id" class="btn btn-primary">Edit</a>

Upvotes: 0

Related Questions