ASP.NET MVC + WebForms - 路由冲突

时间:2012-03-01 09:37:01

标签: asp.net-mvc asp.net-mvc-routing

我正在构建一个简单的报表Web应用程序,用于使用ASP.NET MVC3 + WebForms呈现报表。报表本身由ReportViewer ASP.NET WebForms控件呈现,但我想使用ASP.NET MVC创建参数条目。

我希望所有请求都遵循“〜/ {controller} / {action} / {parameters}”的默认路由方案,但~/Report的请求除外,这些请求应转到报告呈现Web窗体。什么是正确的方法?

扩大一点..

我在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");
}

网址变得很好,但问题是,当请求进来时,第一条路线也会吃掉第二条路线的网址,即~/Report?id=7尝试调用Index方法在ReportController(不存在)。

如果我更改它以使“报告呈现”路线位于“默认”路线之前,如下所示:

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页)中的路由章节:

  

... 使用所有路线的名称和   生成URL时始终使用路径名称。大多数时候,让路由选择哪个   你想用来生成一个URL的路由真的让它失去了机会,这不是那样的   与强迫控制狂的开发人员坐在一起。通常,在生成URL时   确切地知道您要链接到哪条路线,因此您也可以按名称指定它。

上面提到的部分讨论了与我描述的情况非常相似的情况。

但是由于Html.ActionLink()没有路由名称参数的重载,这是否意味着如果有这样的路由,我无法在整个应用中的任何地方可靠地使用它?

1 个答案:

答案 0 :(得分:1)

这是我发现的最佳解决方案 我已使用MapPageRoute注册了我的路线(我已将报告页面放在名为Reports 的文件夹下)

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 })

我可以在我的WebForm页面中获得 id ,如下所示:

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

希望它有所帮助。

<强>更新

我创建了一种扩展方法,让您的生活更轻松:

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 ,但我的签名有问题,而且我不是这方面的专家。