2
votes

This question is being based off of a similar question titled, "ASP.NET MVC Relative Paths", located here.

I understand that issues arise concerning absolute and relative paths when developing an ASP.NET application...especially an ASP.NET MVC application. Throughout the application lifecycle, I've been using something similar to the following to resolve paths in my ASPX pages:

<script type="text/javascript" src="<%=Url.Content("~/Scripts/jquery-1.2.6.js")%>"></script>

I am unable to leave the paths as relative, because it is getting moved around from the development tier to the staging tier to the production tier, and it may reside in a slightly different folder structure within IIS.

My question, however, is what can I do about relative paths located in Javascript files? How can they be resolved? Up to this point, I have been embedding the Javascript for each page into the page itself, so I can resolve the URL using an approach similar to above. This results in Javascript looking something like this:

$(function() {
    $.getJSON('<%= Url.Content("~/home/test/1") %>', null, function(data) {
        // Do stuff in here
    });
});

This works fine, of course until I move everything out of the ASP.NET page and into a centrally located Javascript file. As suggested by the aforementioned question:

Or you can use document.location.host to build the fully qualified path name within the javascript: document.location.host + "/Content/Images/MyImage.jpg"

Another method is to have ASP.NET build this part of the script dynamically so that the fully qualified path name is injected.You can do this by using ScriptManager.RegisterStartupScript or ScriptManager.RegisterScriptBlock

The application is a rather heavy Javascript user, so I'm unsure if the second option is going to work. Is there a more elegant way to resolve this issue other than the first option? What have you guys done to resolve this issue? Any help would be greatly appreciated. Thanks.

2

2 Answers

3
votes

One way could be is to have your JS script take a reference to an object, and this object would be constructed in the view/partial that contains the relative pathing you need. Then your JS file code can use this object to instantiate the paths as you need.

Kind of a pain, but that would work, as in:

var paths = 
{
    imagePath: '<%= Url.Content("~/Content/Images/MyImage.jpg") %>'
}

var obj = myJSFileObject.Load(paths);
//continue

HTH

0
votes

While I'm not using MVC (yet), my Page class has a collection for script paths, which are added automatically to the top or bottom of the HTML page as it is rendered (as appropriate).

Some script files are registered by the Page class itself from an application-wide list of scripts every page needs, others are registered by the individual pages.

In either case, the registration looks something like this:

 MyPage.AddScriptBlock(Path:="{apppath}scripts/myscript.js", LoadAtTop:=True)

The Page class does a quick search/replace on the as it generates SCRIPT tags for them when rendering:

 Writer.Write(New JavascriptBlock( _
    thisscript.Path.Replace("{apppath}", AppPath()))

The function AppPath() looks like this:

 Private Shared pvtAppPath As String
 Public Shared Function AppPath() As String
If pvtAppPath="" Then
   With System.Web.HttpContext.Current.Request
    pvtAppPath = "http://" & .Url.Host & .ApplicationPath
   End With
   If Not pvtAppPath.EndsWith("/") Then pvtAppPath &= "/"
End If
Return pvtAppPath
 End Function

This gives me all the functionality I need:

  1. I can have some JavaScript files loaded by default on every page.
  2. I can have some JavaScript files load only on an individual page.
  3. I can override (1) where needed by removing it from the collection.
  4. I can control (for performance) whether the script is in the HEAD or the bottom of the BODY
  5. I can use the same code on my dev and production machines.
  6. My script tags are guaranteed to be generated in a consistent way.

I don't know exactly how this fits in with MVC, but hopefully it will give you some ideas.