I am creating a simple report web application for rendering reports using ASP.NET MVC3 + WebForms. The reports themselves are displayed using the ASP.NET WebForms ReportViewer control, but I would like to use ASP.NET MVC to create a parameter record.
I would like all requests to be executed according to the default routing scheme '~ / {controller} / {action} / {parameters}', with the exception of requests for ~/Report
, which should go to the WebForm report. What is the right way to do this?
Expand the bit ..
I have two routes in Global.asax.cs
- by 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 are great, but the problem is that when the request comes in, the first route also uses the urls for the second, i.e. ~/Report?id=7
tries to call the Index
method on the ReportController
(which is not).
If I change it so that the report-rendering route reaches the default route, for example:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapPageRoute("report-rendering", "Report", "~/Render.aspx"); routes.MapRoute( "Default",
Now calls to Html.ActionLink () display invalid URLs, i.e.
`@Html.ActionLink("Report list", "Index", "ReportList")`
Renders
`http:`
My current workaround is to set the default route first, adding a regular expression constraint to ignore queries for the Report controller, for example:
routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults new { controller = @"(?!report$).*" } );
It does not seem clean. Again, What is the correct way to do this?
In addition, I have not yet decided how to pass the parameters to the rendering form: I could use both request or POST parameters. I assume the query parameters are more flexible. What is the best practice here?
EDIT:
While researching the answer from @LeftyX, it seems like I found the answer. To quote P. Haack from his routing chapter in ASP.NET MVC 3 Professional (Named Routes, chapter 9, p. 233):
... Use names for all of your routes and always use the name of the route when creating URLs. Most of the time, allowing the routing to sort which route you want to use to create the URL does leave it to chance, which is not something that sits well with the obsessive-compulsive control developer. When creating a URL, you usually specify exactly which route you want to map to, so you can specify it by name.
This section discusses a very similar situation with the one I described.
But since Html.ActionLink()
does not have an overload with the route name parameter, does this mean that I cannot reliably use it anywhere in the entire application if you have such a route?