如何设置MVC可移植区域以使用复杂目录结构中的资源?

时间:2013-10-02 18:50:45

标签: asp.net-mvc asp.net-mvc-2 url-routing mvccontrib

我在MVC 2应用程序中使用便携式区域。我在一个文件夹中有一个javascript文件 /Scripts/ViewModels/ViewModel.js但是当我尝试访问它时,我找不到404错误。便携式区域的注册如下:

private void RegisterRoutes(AreaRegistrationContext context)
    {
        context.MapRoute(
          AreaName + "_resources",
          base.AreaRoutePrefix + "/resource/{resourceName}",
          new { controller = "EmbeddedResource", action = "Index"},
          new[] { "MvcContrib.PortableAreas" }
        );

        context.MapRoute(
          AreaName + "_scripts",
          base.AreaRoutePrefix + "/Scripts/{resourceName}",
          new { controller = "EmbeddedResource", action = "Index", resourcePath = "scripts" },
          new[] { "MvcContrib.PortableAreas" }
        );

        context.MapRoute(
            AreaName + "_images",
            base.AreaRoutePrefix + "/images/{resourceName}",
            new { controller = "EmbeddedResource", action = "Index", resourcePath = "images" },
            new[] { "MvcContrib.PortableAreas" }
       );

        context.MapRoute(
            AreaName + "_default",
            base.AreaRoutePrefix + "/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional },
            new[] { "PortableAreaDemo.PortableAreas.Areas.Demo.Controllers", "MvcContrib" }
        );
    }

在视图模板中,我尝试包含脚本文件 <script src="@Url.Content("~/Demo/Scripts/ViewModels/ViewModel.js")"></script> 我得到以下网址/Demo/Scripts/ViewModels/ViewModel.js,但该文件无法访问。我只能访问脚本文件,它们是Scripts文件夹的直接子项。

3 个答案:

答案 0 :(得分:2)

来自路由MSDN Documentation

  

有时您必须处理包含可变数量的URL段的URL请求。定义路径时,可以指定如果URL具有的分段数多于模式中的分段,则额外的分段将被视为最后一个分段的一部分。要以这种方式处理其他段,请使用星号(*)标记最后一个参数。这被称为全能参数。具有catch-all参数的路由也将匹配不包含最后一个参数的任何值的URL。

所以,您应该尝试在脚本路径的参数的开头添加*,例如base.AreaRoutePrefix + "/Scripts/{*resourceName}",,这样可以将参数作为一个包罗万象进行处理。然后,resourceName就可以分配到/ViewModel.js/ViewModels/ViewModel.js。如果没有*/ViewModels段将被视为另一个段,这会导致路由引擎不将此路由评估为匹配,并继续通过已定义的路由,404为没有路由匹配提供的URL路径模式的结果。

答案 1 :(得分:0)

编写以下路由[必须在“/ Scripts / {resourceName}”路由之前插入]

context.MapRoute(
      AreaName + "_viewmodels_scripts",
      base.AreaRoutePrefix + "/Scripts/viewmodels/{resourceName}",
      new { controller = "EmbeddedResource", action = "Index", resourcePath =     "scripts.viewmodels" },
      new[] { "MvcContrib.PortableAreas" }
    );

并且不要忘记为脚本设置“Build Action”到“Embedded Resource”

答案 2 :(得分:0)

已回答here

在每个文件类型的Web.Config中添加:

<system.webServer>
  <handlers>
    <add name="js" path="*.js" verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="File" preCondition="integratedMode" />
  </handlers>
</system.webServer>

这将使IIS尝试使用已定义的路由,而不是搜索静态文件。