I'm building a simple report Web app for rendering reports using ASP.NET MVC3 + WebForms. The reports themselves are rendered by the ReportViewer ASP.NET WebForms control, but I'd like use ASP.NET MVC to create the parameter entry.
I'd like to have that all requests follow the default routing scheme of '~/{controller}/{action}/{parameters}', except requests for ~/Report
, which should go to the report rendering WebForm. What's the right way to do this?
Expanding a bit..
I have two routes in Global.asax.cs
- the default one and one for the WebForms page.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapPageRoute("report-rendering", "Report", "~/Render.aspx");
}
The URLs get rendered fine, but the problem with this is that when the request comes in, the first route also eats the URLs for the second one, i.e. ~/Report?id=7
tries to call the Index
method on the ReportController
(which doesn't exist).
If I change it so that the 'report-rendering' route comes before the 'Default' route, like so:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapPageRoute("report-rendering", "Report", "~/Render.aspx");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Now calls to the Html.ActionLink() render incorrect URLs, i.e.
`@Html.ActionLink("Report list", "Index", "ReportList")`
Renders
`http://localhost:49910/Report?action=Index&controller=ReportList`
My current workaround puts the 'Default' route first, while adding a regex constraint to ignore requests for the 'Report' controller, like so:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { controller = @"(?!report$).*" }
);
This doesn't feel clean. Again, What's the right way of doing this?
Also, I haven't yet decided how I'll pass the parameters to the rendering form: I could use both query parameters or POST them. I'm guessing that query params are more flexible. What's the best practice here?
EDIT:
While researching the answer by @LeftyX, seems like I've found an answer. To quote P. Haack from his Routing chapter in the Professional ASP.NET MVC 3 (Named Routes, Chapter 9, page 233):
... Use names for all your routes and always use the route name when generating URLs. Most of the time, letting Routing sort out which route you want to use to generate a URL is really leaving it to chance, which is not something that sits well with the obsessive-compulsive control freak developer. When generating a URL, you generally know exactly which route you want to link to, so you might as well specify it by name.
The mentioned section discusses a very similar situation to the one I described.
But since Html.ActionLink()
doesn't have an overload with the route name parameter, does this mean I cannot reliably use it anywhere in the entire app if have a route like this?