2
votes

So, we're updating a project from web forms to .NET MVC. To support other applications that deep link into our application, I'm trying to add attribute routes to the relevant controller actions that mimic the old web forms paths.

I have an event action on the Home controller. The configuration has a route for this to remove the controller name.

routes.MapRoute(
    name: "eventdetails_nohome",
    url: "event/{id}/{occurrenceid}",
    defaults: new { Controller = "Home", action = "Event", occurrenceid = UrlParameter.Optional },
    constraints: new { id = @"\d+", occurrenceid = @"\d+" }
);

That route works just fine for routes like http://myapp/event/123/456, and the default routing like http://myapp/home/event?id=123&occurrenceid=456 also works.

So far so good, but if I add this route attribute to the action:

[Route("~/ViewEvent.aspx")]
public ActionResult Event(int id, int occurrenceid)

Then the only route that works is http://myapp/ViewEvent.aspx?id=91918&occurrenceid=165045. The routes that worked before start returning

Server Error in '/' Application.

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

Requested URL: /event/123/456

I've used the routedebugger extension, and I can verify that even with the attribute route, my old route is still the first to work. So why would I be getting "resource cannot be found" errors?

Note: as a workaround, I've found that I can just do a traditional route configuration like

routes.MapRoute(
    name: "Legacy event",
    url: "ViewEvent.aspx",
    defaults: new { Controller = "Home", action = "Event" }
);

I'm still curious why the attribute route would break existing routes, though, as I thought you were supposed to be able to use both at the same time.

1
That is because the attribute route overrides the convention based route. You will need to use multiple route attributes on the action. I'm on mobile and will post an answer as soon as I get back to my workstation.Nkosi

1 Answers

2
votes

Take a look at Attribute Routing in ASP.NET MVC 5

Another article with the same heading

Attribute Routing in ASP.NET MVC 5

Attribute routes overrides the convention based route. If you use more than one URL for action, you can use multiple route attributes on the action...

    [Route("event/{id:int}/{occurrenceid:int}")]
    [Route("event")]
    [Route("~/ViewEvent.aspx")]
    public ActionResult Event(int id = 0, int occurrenceid = 0) {
        return View();
    }

The following URLs all routed to the above action.

http://myapp/event/123/456
http://myapp/home/event?id=123&occurrenceid=456
http://myapp/ViewEvent.aspx?id=91918&occurrenceid=165045