2

I am having some difficulty aligning my paths without a hardcode in javascript. I am running an asp.net MVC3 web application.

If my path is of the form

var url = 'http://serverNameHardcode/websiteNameHardcode/service/service?param1=' + param;

Then things work fine when I do

 $.get(url,
        {},
        function (data) {alert('callback success');},'json');

I would like to create a relative path. I tried

var url = 'service/service?param1=' + param;

And this works when I run locally and also in Firefox, but not in IE7. When I publish to the server without the hardcode the callback never fires. I know MVC-3 adds some complexity to routing, but I do not know if it applies to this situation; so, I marked this question as such.

How should I setup my path so I don't need hardcodes?

5
  • Are you certain it is a url issue and not, say, a scripting error? That path looks just fine to me and should be compatible with all mainstream browsers AFAIK. Commented Sep 29, 2011 at 18:07
  • @mellamokb - What I do know is that the hard coded path works. The path without the hardcode does not. When I run locally, there is no need to hardcode. My guess is that MVC-3 is complicating things beyond the norm. Commented Sep 29, 2011 at 18:11
  • Give us some more info about the url you're hitting. What it is, what project its in, who owns it, is it the path to a controller or a fixed path to a wcf service endpoint, etc. Commented Sep 29, 2011 at 18:16
  • Start by firing up firebug or chromes js console and look at what the incorrect url is in the XHR. That will give you a hint as to whats messing it up Commented Sep 29, 2011 at 18:19
  • @Allen - They are controllers. I use controllers as services. I need the URL to the website root, "~/" or possibly the whole first part of the URL http://mysite/mysubdomain. Actually, its probably the latter. Knowing just the service path gives me what I already know (the second url which does not work). Commented Sep 29, 2011 at 18:29

5 Answers 5

7

Just write out the app path as a global js variable from your master view, then compose links as

APPPATH + "path/whatever"
Sign up to request clarification or add additional context in comments.

2 Comments

Add this to the top of your shared layout <script type="text/javascript"> var AppPath = '@Url.Content("~/")' </script> and then use it as BNL said above
While this works, I find adding a global setting breaks any encapsulation plugins may have. I like to simply plug things in and have them work without modifying master pages etc. I have suggested an alternative below I have just used on a production project that avoids these problems.
3

Just had to solve this for one of my jQuery plugins, where it is preferable not to modify anything global (i.e. outside the scope of the plugin use) so I had to disregard the marked answer.

I also found that because I host DEV locally in IIS I could not use a root-relative path (as localhost is not the root).

The solution I came up with extended what I had already started with: a data-controller attribute specifying which controller to use in the element I am applying my plugin to. I find it preferable to data-drive the controller names so the components can be more easily reused.

Previous:

   <div data-controller="Section">

Solution:

   <div data-controller="@Url.Content("~/Section")">

This injects the server root (e.g. /Test.WindowsAzure.Apr2014/ before the controller name so I wind up with /Test.WindowsAzure.Apr2014/Section which is perfect for then appending actions and other parameters as you have. It also avoids having an absolute path in the output (which takes up extra bytes for no good reason).

In your case use something like:

// Assuming $element points to the element your plugin/code is attached to...
var baseUrl = $element.data('controller');
var url = baseUrl + '/service?param1=' + param;

Update:

Another approach we now use, when we do not mind injecting a global value, is Razor-inject a single global JavaScript variable onto window in the layout file with:

<script>
   window.SiteRoot = "@Url.Content("~/")";
</script>

and use it with

var url = window.SiteRoot + '/service?param1=' + param;

1 Comment

i preferred this approach, as it doesn't require messing with any master files.
2

One option:

var editLink = '@Url.Action("_EditActivity", "Home")';
$('#activities').load(editLink + "?activityID=" + id);

another example:

var actionURL = '@Url.Action("_DeleteActivity", "Home")';
$('#activities').load(actionURL + "?goalID=" + gID + "&activityID=" + aID);

If you don't need to add to the string:

$('#activities').load('@Url.Action("_Activities", "Home", new { goalID = Model.goalID},null)');

3 Comments

This works if your Javascript was inline with your Razor views. If your JS are in external files (as they should), you'll also have to define them as views as well (with a matching controller).
This just gives me 'Home/EditActivity'. I don't understand how this is different from the second URL I posted in the question. I believe I need to find the server path http://server/subdomain.
That's possible - I always thought using @Url.Action (in place of hard coding a path) will automatically handle creating the correct path based on the structure
2

I really need the path to get this to work, maybe its IE7. Who knows. But this worked for me.

Grab the URL and store it somewhere. I chose to implement the data attribute from HTML5.

<div id="websitePath" data-websitePath='@Request.Url.GetLeftPart(System.UriPartial.Authority)@Request.ApplicationPath'></div>

Then when you need to perform some AJAX or otherwise use a URL in javascript you simply refer to the stored value. Also, there are differences in the versions of IIS (not cool if your devbox is IIS5 and your server is IIS7). @Request.ApplicationPath may or may not come back with a '/' appended to the end. So, as a workaround I also trim the last character if it is /. Then include / as part of the url.

var urlprefix = $('#websitePath').data('websitepath');
urlprefix = urlprefix.replace(/\/$/, "");
var url = urlprefix + '/service/service?param1=' + param;

2 Comments

This is really brilliant. I tried so many things. But this is the only thing that worked
@DotNetBeginner: I have suggested a much simpler alternative below as you do not need a full URL (only a root relative path).
-1

While the accepted answer is correct I would like to add a suggestion (i.e. how I do it).

I am using MVC, and any ajax request goes to a controller. My controllers have services so if a service call is required the controller will take of that.

So what's my point? So if ajax always communicates with a controller, then i would like to let the MVC routing resolve the path for me. So what I write in Javascript for url is something like this:

url: 'controller/action'

This way there is no need for the root path etc...

Also, you can put this in a separate Javascript file and it will also work whereas @Url.Content will need to be called on the view.

3 Comments

-1: This solution does not work as the link is relative to the current page. FYI MVC ActionLinks always inject a root relative path (including a '/ and any virtual IIS folder). If you simply make your example a root relative path it still will not work if it is hosted in a virtual application/folder. Basically tried this first then realised it could never work.
Didn't think we were talking about ActionLinks. We are talking about Javascript AJAX calls.
The ActionLink comment was purely to point out MVC links are normally root-relative. Your link is page relative and will not work (I know, I tried all options).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.