65

In external js file, I cant use

url = "@Url.Action("Action", "Controller")" 
//url output : @Url.Action("Action", "Controller")
//I get IllegalPath Name error.

When I write like this:

url = "/Controller/Action"

And If project is under a sub folder, then scripts do not work. I need something like this as relative Url:

url = "~/Controller/Action"

How can ı do this? Thanks.

AliRıza Adıyahşi
  • 15,658
  • 24
  • 115
  • 197
  • How about `url = '~' + "@Url.Action("Action", "Controller")" ` – Musa Nov 30 '12 at 07:12
  • 1
    `@Url.Action("Action", "Controller")` output is `@Url.Action("Action", "Controller")` so your suggestion output is `~@Url.Action("Action", "Controller")` I need `Site/subFolder/controller/Action` – AliRıza Adıyahşi Nov 30 '12 at 07:15

6 Answers6

167

As .js files are not parsed by asp.net mvc view engine, you simply cannot use any c# code in there. I would suggest using unobtrusive approach, something like this

<div id="loader" data-request-url="@Url.Action("Action", "Controller")"></div>

And in javascript, use value of data-request-url

$(function(){
   $('#loader').click(function(){
       var url = $(this).data('request-url');
       alert(url);
   });
});
archil
  • 39,013
  • 7
  • 65
  • 82
  • 1
    Tip top - Thank you. Makes complete sense after the fact. Time to farm out lots of JQUery to external scripts. Thanks again! – AntDC Jun 14 '17 at 12:15
8

I'm not sure if this is the most elegant solution, but what I did was differentiating between registers and the real implementation in the external scripts, so that:

<script>...</script>
... include all the external scripts I need

$(document).ready(function(){

    //get all the information you need from your MVC context 
    //before going out of context and into the scripts
    var url = '@Url.Action("Action", "Controller")'; 


     RegisterMyFunction(url, other parameters ..);
     RegisterAnotherFunction(url, others...);
}

So that in my views I only had the register functions and the scripts contained the special values as a parameter to do whatever I wanted.

Hope it helps,

Jorge Alvarado
  • 2,664
  • 22
  • 33
  • I would make the surrounding quotes single quotes `'`, so they visually differ from the quotes of the `Url.Action` Method. Anyway, something like this will be the way to go (+1) – Dennis Nov 30 '12 at 07:45
  • 1
    @Chips_100 thanks buddy, you are right, I fixed the code for better readibility. – Jorge Alvarado Nov 30 '12 at 08:31
4

Here's a pattern I've been using. It's a bit more steps, but I like that all of my urls are in one organized location in the View.

At the bottom of my View I will include a Scripts Section that contains the urls like so:

@section Scripts
{
    <script type="text/javascript">
        myJavaScriptObject.firstUrl = '@Url.Action("Action1", "Controller", new {id = Model.Id})';
        myJavaScriptObject.secondUrl = '@Url.Action("Action2", "Controller", new {id = Model.Id})';
    </script>
}

Inside of my JavaScript Class (which is in an external file) I will reference the url like so:

var myJavaScriptObject = {
    firstUrl: '',
    secondUrl: '',
    docReady: function() {
        $.get(myJavaScriptObject.firstUrl, function(data) { do something...  });
    }
}

I realize the entries don't need to be referenced inside of the Class, but I like to have them there for my own housekeeping.

Airn5475
  • 2,452
  • 29
  • 51
0

As accepted answer described, you can not use any C# code in external JS file. Here is what I normally do if I need to pass few controller links to my external .js file.

In C# (.cshtml)

<script src="~/js/myfile.js"></script>

<script type="text/javascript">

    var url1 =  "@Url.Action("ActionName", "ControllerName", new { Param = ViewBag.Param })";  
    var url2 = "@Url.Action("AnotherAction", "AnotherController")";

    $(function() {
        window.initScript(url1, url2);
    });

</script>

In myfile.js

var _url1;
var _url2;

function initScript(url1, url2) {
    _url1 = url1;
    _url2 = url2;

   // other init. codes...

}
Muhammad Saqib
  • 2,185
  • 3
  • 35
  • 48
0

You can use Hidden fields to do the same (on Master/Individual views).

View page:

@Html.Hidden("commonUrlTrack", Url.Action("Action_Method_Name", "Controller_Name"))

<button onclick="commonFunction()">Click Me</button>

JS File:

function commonFunction() {
    var url = $("#commonUrlTrack").val();        
    alert(url);        
}
Dinesh Gaud
  • 121
  • 1
  • 10
0

I put this code in my _Layout.cshtml in head

<script type="text/javascript">
    var yourCompanyUrlPrefix = '@Url.Action("", "")';
  </script>

and then use yourCompanyUrlPrefix in any js file

Jakub
  • 131
  • 2