ASP.NET MVC + WebForms - route conflict

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", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); } 

Now calls to Html.ActionLink () display invalid URLs, i.e.

 `@Html.ActionLink("Report list", "Index", "ReportList")` 

Renders

 `http://localhost:49910/Report?action=Index&controller=ReportList` 

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?

+6
source share
1 answer

This is the best solution I found out.
I registered my route with MapPageRoute (I placed my report page under the Reports folder)

 public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapPageRoute( "report-rendering", "Report/{id}", "~/Reports/Report.aspx" ); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } 

I created my link using RouteLink so you can specify a route:

 @Html.RouteLink("Report list", "report-rendering", new { id = 7 }) 

and I can get the id on my WebForm page as follows:

 protected void Page_Load(object sender, EventArgs e) { var id = Page.RouteData.Values["id"] as string; } 

Hope this helps.

UPDATE

I created an extension method to make your life easier:

 public static class ExtensionMethods { public static MvcHtmlString WebFormActionLink(this HtmlHelper htmlHelper, string linkText, string ruoteName, object routeValues) { var helper = new UrlHelper(htmlHelper.ViewContext.RequestContext); var anchor = new TagBuilder("a"); anchor.Attributes["href"] = helper.RouteUrl(routeName, routeValues); anchor.SetInnerText(linkText); return MvcHtmlString.Create(anchor.ToString()); } } 

It would be best to use ActionLink instead of WebFormActionLink , but I have problems with signatures, and I'm not an expert in this.

+1
source

Source: https://habr.com/ru/post/909721/


All Articles