动态URL路由

时间:2013-08-24 13:21:02

标签: c# asp.net asp.net-mvc asp.net-mvc-4

此应用在RouteConfig.cs中配置了多个路由。例如,我定义了以下两条路线:

routes.MapRoute(
  name: "MyPage-Demo",
  url: "pages/page-title/demo",
  defaults: new { controller = "Root", action = "PageDemo" }
);

routes.MapRoute(
  name: "MyPage",
  url: "pages/page-title/{resource}",
  defaults: new { controller = "Root", action = "Page", resource = UrlParameter.Optional }
);

有人访问的每个页面都有一个指向“演示”的链接。访问http://localhost/pages/page-title即可访问页面。这很好。

当用户点击“演示”链接时,系统会将其重定向到位于http://localhost/pages/page-title/demo的页面。这很好。

我的问题是演示页面可能引用了复杂的嵌套结构。该结构由JavaScript,CSS,图像等组成。用于演示目的的内容。这些嵌套资源都不能找到。但是,我不知道如何设置我的路由来解释这些嵌套文件。

我确信我需要更新控制器的PageDemo操作。但是,我不确定

a)如何以允许不同结构和

的方式这样做

b)如何更新我的路由配置以考虑这些嵌套结构。

有办法做到这一点吗?实际上,我将有多个页面和多个演示。出于这个原因,我希望有一些比硬编码方法更可重用的东西。

7 个答案:

答案 0 :(得分:2)

如果您只需要提供物理存储在路径中的文件,您应该可以忽略该路由,例如:

routes.IgnoreRoute("pages/page-title/demo/resources/{*resource}");

这将绕过MVC尝试将请求路由到控制器。

或者你可以通过文件扩展名:

routes.IgnoreRoute("{file}.js");
routes.IgnoreRoute("{file}.css");

(代码未经测试,但看起来你在尝试做类似的事情:) https://stackoverflow.com/a/3112192/486620

答案 1 :(得分:2)

IF 我理解:

问题似乎是您的MyPage-Demo路线:

routes.MapRoute(
  name: "MyPage-Demo",
  url: "pages/page-title/demo",
  defaults: new { controller = "Root", action = "PageDemo" }
); 

{resource}具体,而您的MyPage路线 IS

如果您更改路线以获取{resource}

routes.MapRoute(
  name: "MyPage-Demo",
  url: "pages/page-title/demo/{resource}",
  defaults: new { controller = "Root", 
        action = "PageDemo", resource = UrlParameter.Optional  });

然后你的行动方法可以

  1. 使用适当的资源设置返回特定视图
  2. 设置Viewbag属性,其中包含指向特定资源的路径

  3. 如果 这符合您的意图,这些路线可以合并到

    routes.MapRoute(
      name: "MyPage-Demo",
      url: "pages/{action}/{resource}",
      defaults: new { controller = "Root", 
            action = "PageDemo", resource = UrlParameter.Optional  });
    
    1. /pages/PageDemo/{resource}解析为Controller=pagesaction = PageDemo
    2. /pages/demo/{resource}解析为Controller=pagesaction = demo
    3. 此约定允许您灵活地创建更多{resource}依赖链接

答案 2 :(得分:1)

浏览器中,右键单击演示页面=>选择查看页面来源

在这里,您可以在演示页面中找到 CSS Js 文件的链接。单击那些js / css文件链接。检查是否有重定向到正确/预期的位置。否则你可以相应地设置 Css / Js 文件 URL 因为,根据演示页面,每个PageDemo都有自己独特的 JS / Images / css结构< / strong>等等

答案 3 :(得分:0)

你是如何引用你的JS和CSS文件的?

如果你使用像~/Content/Styles/Site.css之类的代字号,无论你在虚拟路径的哪个位置都不会有任何问题。

答案 4 :(得分:0)

也不是100%确定我直接回答了您的问题,但假设您尝试访问的资源嵌套在镜像页面结构的文件夹结构中 - 您遇到的问题是如何忽略到这些路线的路线,而不必提前知道它们可能是什么?

这很好地解释了:https://stackoverflow.com/a/30551/1803682

我会问:

  1. 正如@PKKG在回答中指出的那样 - 页面源中的链接是否符合您的期望?
  2. 这个每个演示内容如何服务:例如通过服务而不是静态文件?

答案 5 :(得分:0)

这个答案包含两种方法。第二个可能更适合您的场景。第一个可能更适合一般的mvc项目

接近一个

我建议在内容文件夹中创建一个有组织的结构来存储脚本和css文件,即

/Content/Demos/Page-Title-1/
/Content/Demos/Page-Title-2/
/Content/Demos/Page-Title-3/

/Content/Demos/Common/

然后创建一个包来呈现每个页面标题的脚本和css文件

bundles.Add(new StyleBundle("~/Demo/page-title/css").Include(
          "~/Content/Demos/Page-Title-1/csscontent1.css",
          "~/Content/Demos/Page-Title-1/csscontent2.css",
          "~/Content/Demos/Page-Title-1/csscontent3.css",
          "~/Content/Demos/Page-Title-1/csscontent4.css"));

bundles.Add(new StyleBundle("~/Demo/page-title/js").Include(
      "~/Content/Demos/Page-Title-1/jscontent1.css",
      "~/Content/Demos/Page-Title-1/jscontent2.css",
      "~/Content/Demos/Page-Title-1/jscontent3.css",
      "~/Content/Demos/Page-Title-1/jscontent4.css"));

这将允许您使用几行方法在演示页面上渲染脚本,即

@Styles.Render("~/Demo/page-title/css");
@Scripts.Render("~/Demo/page-title/jss");

@Styles.Render("~/Demo/common/css");
@Scripts.Render("~/Demo/common/css");

当您更改/ Content / Demos / Page-Title /文件夹中的文件时,您将不得不更新全局.asax中的文件。 如果您选择,可以捆绑和缩小文件以节省第一页加载的带宽和加载时间。


接近两个。

(仍然使用以下文件夹结构

/Content/Demos/Common/

/Content/Demos/Page-Title-1/
/Content/Demos/Page-Title-2/
/Content/Demos/Page-Title-3/)

制作一个html助手来引用所有脚本&amp;文件夹中的内容

它的用法是     @ Asset.RenderAssets('〜/ folderdirectory')

并且助手会做类似

的事情
@helper RenderAssets (stirng directory){

@* scrape the directory for all script files*
var scripts = find all scripts in the directory

@* include the script files *@
for each script
  <script src=" ... .js"></script>


@* scrape the directory for all cssfiles*
var styles = all css in the directory

@* include the css files *@
for each style
<link rel='stylesheet' type="text/css" href=" ... .css">

}

这将是每个演示视图中的一些行用法

@Asset.RenderAssets( '~/Content/Demos/Common')
@Asset.RenderAssets( '~/Content/Demos/Page-Title')

你可能需要也可能不需要在global.asax或RouteConfig.cs文件中将其与一两行相配对(参见来源3)

routes.IgnoreRoute("/Content/Demos/{page}/{script}.js");
routes.IgnoreRoute("/Content/Demos/{page}/{style}.css");

相关消息来源 创建html助手看看 http://weblogs.asp.net/scottgu/archive/2011/05/12/asp-net-mvc-3-and-the-helper-syntax-within-razor.aspx

使用bundle和minifcation(scripts.render方法)看看 http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification

phill haakk说可能不需要将其与忽略路线配对! https://stackoverflow.com/a/30551/1778606

鼓励评论和编辑。

答案 6 :(得分:0)

MVC看不到所有静态内容(.js,.css,.html,.png)(除非在web.config中将modules / runAllManagedModulesForAllRequests设置为true)。静态内容扩展在IIS配置“模块映射”中定义,并使用StaticFileHandler模​​块(而不是.NET模块)。

因此静态内容必须通过其相对于当前路径(当前html页面的路径)的物理路径来引用。

最佳解决方案是使用网站根目录中的绝对链接。与/content/demo1/demo1.html一样,将所有js,css放在/ content / demo1 /中,并在demo1.html中使用相对于/ content / demo1 /文件夹的路径(.html所在的位置)。即:将demo1.css放在同一个文件夹中。

demo1.html的链接是demo 1