Razzie
Razzie

Reputation: 31222

Getting RouteData for actions with RouteAttribute

I have a custom IRouter implementation, which looks in its basic form like this, for simplicity's sake I hardcoded some values:

public class MyRouter : IRouter
{
  private readonly IRouter router;
  public MyRouter (IRouter router)
  {
    this.router = router;
  }

  public async Task RouteAsync(RouteContext context)
  {
    context.RouteData.Values["controller"] = "Home";
    context.RouteData.Values["action"] = "Index";
    context.RouteData.Values["area"] = "";
    await router.RouteAsync(context);
  }
}

This works for a simple controller without a [Route] attribute defined:

public class HomeControlller
{
  public IActionResult Index()
  {
    return View();
  }
}

Again, this works correctly. Going to / will show the page. However, as soon as I add [Route] attributes, I get a 404:

[Route("foo")]
public class HomeControlller
{
  [Route("bar")]
  public IActionResult Index()
  {
    return View();
  }
}

Now, if I go to /foo/bar, I will see the page. However, if I go to /, I get a 404. How can I fix this? If I look at the RouteData values when going to /foo/bar, I still see the values Home and Index as values for controller and action, respectively.

Upvotes: 1

Views: 606

Answers (1)

Edward
Edward

Reputation: 29976

This is by design.

Actions are either conventionally routed or attribute routed. Placing a route on the controller or the action makes it attribute routed. Actions that define attribute routes cannot be reached through the conventional routes and vice-versa. Any route attribute on the controller makes all actions in the controller attribute routed.

Reference: Mixed routing: Attribute routing vs conventional routing.

For Conventional router, it is using MvcRouteHandler, and Attribute route will use MvcAttributeRouteHandler. When Controller or Action used with Route[], it will not go to Converntional router when you request the specific method.

Upvotes: 1

Related Questions