我正在使用ASP.NET MVC3 + WebForms构建一个简单的报告Web应用程序来呈现报告。报告本身由ReportViewer ASP.NET WebForms控件呈现,但我想使用ASP.NET MVC创建参数输入。
我希望所有请求都遵循“~/{controller}/{action}/{parameters}”的默认路由方案,除了对“~/Report”的请求,它应该转到报告呈现WebForm。如何正确实现?
稍微扩展一下...
在Global.asax.cs中有两个路由 - 默认路由和一个用于WebForms页面的路由。
URL地址的呈现很好,但问题在于当请求到来时,第一个路由也会捕获第二个路由的URL,即
现在对Html.ActionLink()的调用会呈现错误的URL,即:
呈现。
我希望所有请求都遵循“~/{controller}/{action}/{parameters}”的默认路由方案,除了对“~/Report”的请求,它应该转到报告呈现WebForm。如何正确实现?
稍微扩展一下...
在Global.asax.cs中有两个路由 - 默认路由和一个用于WebForms页面的路由。
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");
}
URL地址的呈现很好,但问题在于当请求到来时,第一个路由也会捕获第二个路由的URL,即
~/Report?id=7
尝试调用ReportController
中的Index
方法(该方法不存在)。如果我将“report-rendering”路由放在“Default”路由之前,就像这样: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
);
}
现在对Html.ActionLink()的调用会呈现错误的URL,即:
`@Html.ActionLink("Report list", "Index", "ReportList")`
呈现。
`http://localhost:49910/Report?action=Index&controller=ReportList`
我的当前解决方法是将“默认”路由放在最前面,同时添加一个正则表达式约束来忽略对“报告”控制器的请求,如下所示:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { controller = @"(?!report$).*" }
);
这感觉不太干净。再次问一下,什么是正确的方法?
此外,我还没有决定如何将参数传递给渲染表单:我可以使用查询参数或将其POST。我猜查询参数更灵活。这里有什么最佳实践?
编辑:
在查找@LeftyX的答案时,似乎我已经找到了一个答案。引用P. Haack在Professional ASP.NET MVC 3(命名路由,第9章,第233页)中的Routing章节:
... 为所有路由使用名称,并始终在生成URL时使用路由名称。大多数情况下,让Routing确定您要使用哪个路由来生成URL实际上是交给机会,这不是一个好的开发者所喜欢的事情。当生成URL时,您通常确切地知道要链接到哪个路由,因此最好通过名称指定它。
上述部分讨论了与我描述的非常相似的情况。
但是由于Html.ActionLink()
没有带路由名称参数的重载,这是否意味着如果我有一个像这样的路由,就无法在整个应用程序中可靠地使用它?
reportId
而不是id
,并且不指定默认值,则链接渲染将不会选择此路由。也就是说,对于路由routes.MapPageRoute("report-rendering","Report/{reportId}", "~/Render.aspx");
,这个:@Html.ActionLink("Page 2", "Page", "Home", new { id = 2 }, null)
生成的是:http://localhost:49910/Home/Page/2,但是这个:`@Html.RouteLink("Run report", "report-rendering", new { reportId = 1 })`将生成:http://localhost:49910/Report/1。 - Ronald Zarīts