Zoliqa
Zoliqa

Reputation: 1025

How to set up MVC portable areas to use resources from a complex directory structure?

I'm using portable areas in an MVC 2 application. I have a javascript file in a folder /Scripts/ViewModels/ViewModel.js but when I try to access it, I get a 404 error for not found. The registration for the portable area looks like this:

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

In a view template I tried to include the scripts file with <script src="@Url.Content("~/Demo/Scripts/ViewModels/ViewModel.js")"></script> and I get the following url /Demo/Scripts/ViewModels/ViewModel.js but the file is not accessable. I can only access script files which are direct children of the Scripts folder.

Upvotes: 3

Views: 1093

Answers (3)

ceetheman
ceetheman

Reputation: 836

Answered here

In the Web.Config add for each file type:

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

This will make IIS try to use the defined routes instead of searching for the static file.

Upvotes: 0

Oren
Oren

Reputation: 1

Write the following route [must be inserted before the "/Scripts/{resourceName}" route]

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

and don't forget to set the "Build Action" to "Embedded Resource" for your scripts

Upvotes: 0

Claies
Claies

Reputation: 22323

from the MSDN Documentation on routing,

Sometimes you have to handle URL requests that contain a variable number of URL segments. When you define a route, you can specify that if a URL has more segments than there are in the pattern, the extra segments are considered to be part of the last segment. To handle additional segments in this manner you mark the last parameter with an asterisk (*). This is referred to as a catch-all parameter. A route with a catch-all parameter will also match URLs that do not contain any values for the last parameter.

so, you should try adding an * to the beginning of the argument for your scripts path, eg, base.AreaRoutePrefix + "/Scripts/{*resourceName}", which would allow for the parameter to be handled as a catch-all. The resourceName would then be able to be assigned to either /ViewModel.js or /ViewModels/ViewModel.js. without the *, the /ViewModels segment is treated as another segment, which causes the Routing Engine to not evaluate this route as a match, and continue through the defined routes, and the 404 is a result of no routes matching the pattern of the URL path provided.

Upvotes: 2

Related Questions