ASP.NET MVC + WebForms - 路由冲突
我正在构建一个使用ASP.NET MVC3 + WebForms呈现报表的简单报表Web应用程序。报告本身由ReportViewer ASP.NET WebForms控件呈现,但我想使用ASP.NET MVC创建参数条目。ASP.NET MVC + WebForms - 路由冲突
我想有所有的请求遵循“〜/ {控制器}/{行动}/{参数}”,除了~/Report
请求,这应该去报表呈现的WebForm的默认路由方案。什么是正确的方法来做到这一点?
扩大一点..
我在Global.asax.cs
两条路线 - 默认的一个,一个用于Web窗体页。
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");
}
的网址都会变得很好,但这样做的问题是,当请求到来时,第一条路线也吃网址,第二个,即~/Report?id=7
试图呼吁ReportController
的Index
方法(这不存在)。
如果我改变它使“报告渲染”路线而来的“默认”路线之前,像这样:
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答案,好像我已经找到了答案。为了从Professional ASP.NET MVC 3他的路由章(命名路由,第9章,233页)引述P.哈克:
... 您的所有路由都使用姓名和 始终生成的URL时所使用的路由名称。大多数情况下,让路由选择出你想用来生成一个URL的路由是否真的让它变成了偶然,这对于强迫控制的畸形开发者来说并不是什么好东西。在生成URL时,您通常会知道要链接到哪条路径,因此您不妨通过名称来指定它。
上述部分讨论了与我描述的非常相似的情况。
但由于Html.ActionLink()
没有路由名称参数的重载,这是否意味着我不能在整个应用中的任何地方可靠地使用它,如果有这样的路由?
这是我找到的最佳解决方案。
我登记我的路线与MapPageRoute
(我已经把我的报告页面调用报表一个文件夹下)
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 }
);
}
我创建使用RouteLink我的链接,以便您可以指定要使用的路线:
@Html.RouteLink("Report list", "report-rendering", new { id = 7 })
,我可以得到ID在我的WebForm页面这样的:
protected void Page_Load(object sender, EventArgs e)
{
var id = Page.RouteData.Values["id"] as string;
}
希望它有帮助。
UPDATE:
我创建了一个扩展方法,使您的生活更轻松:
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());
}
}
最好的将是使用ActionLink的,而不是WebFormActionLink但我有签名问题,我不是这方面的专家。
感谢您的回答。我看到你在那里做了什么。由于您添加了{id}参数,因此未为{id}提供值的.RouteLink()调用不再与路由匹配。 但是,在指定id参数时生成路由将与此路由匹配。 This:@ Html.ActionLink(“Page 1”,“Page”,“Home”,new {id = 1},null) 会生成这个:http:// localhost:49910/Report/1?action =页面和控制器=首页 这不是你所期望的,对吧? – 2012-03-01 14:10:35
@ghostskunks:我知道。恐怕您必须使用RouteLink为WebForms生成链接,或者您可以尝试扩展ActionLink。 – LeftyX 2012-03-01 15:19:49
@ghostskunks:我试着把东西放在一起(更新的答案),但正如我所说,我不是专家。这只是一个想法。 – LeftyX 2012-03-01 15:24:09