2012-03-01 123 views
6

我正在构建一个使用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试图呼吁ReportControllerIndex方法(这不存在)。

如果我改变它使“报告渲染”路线而来的“默认”路线之前,像这样:

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()没有路由名称参数的重载,这是否意味着我不能在整个应用中的任何地方可靠地使用它,如果有这样的路由?

回答

1

这是我找到的最佳解决方案。
我登记我的路线与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但我有签名问题,我不是这方面的专家。

+0

感谢您的回答。我看到你在那里做了什么。由于您添加了{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

+0

@ghostskunks:我知道。恐怕您必须使用RouteLink为WebForms生成链接,或者您可以尝试扩展ActionLink。 – LeftyX 2012-03-01 15:19:49

+0

@ghostskunks:我试着把东西放在一起(更新的答案),但正如我所说,我不是专家。这只是一个想法。 – LeftyX 2012-03-01 15:24:09