我正在构建一个简单的报表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()
没有路由名称参数的重载,这是否意味着如果有这样的路由,我无法在整个应用中的任何地方可靠地使用它?
答案 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 ,但我的签名有问题,而且我不是这方面的专家。