Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I handle Asp.net MVC URLs in javascript calls?

I am attempting to write a javascript heavy portion of my Asp.net MVC Web App (this portion of the website is a RIA using Extjs). However, I have come up to a standstill at the correct way to handle URLs in the javascript.

For example, right now I have an Ajax call to the List action in the ObjectsController, which resides in the Reading area. The List action takes a parameter of documentId (int). As of right now, this maps to /Reading/Objects/List since I have no changed routing yet (the site is too young at the moment to finalize routes). Normally in a view, to put this URL in a string I would do @Html.Action("List", "Objects", new { area = "Reading", documentId = 3).

However, this doesn't work when dealing with javascript, since javascript isn't parsed by a viewengine.

To get around this, I have a very small view that returns javascript constants, such as URLs, that is loaded prior to my main application's js files. The issue is that I can't call Html.Action for this action because at constant creation time I (obviously) do not know what documentId the ajax calls are going to be, and if you exclude documentId from the Html.Action call an exception occurs. The documentId could change during the normal workflow of the application.

How do I handle this? I don't want to hardcode the URL to /Reading/Objects/List because if I change my routing for this (for a more user friendly json API), or this web app isn't hosted on the root of the domain, the URL will no longer be valid.

How does everyone else handle MVC URLs in their javascript calls?

like image 514
KallDrexx Avatar asked Nov 24 '10 04:11

KallDrexx


2 Answers

Here's a safe technique that I've been using. Even if your route changes, your JavaScript will automatically conform to the new route:

<script>
var url = '@Url.Action("List", "Objects", new { area = "Reading", documentId = "_documentId_")';
var id = 100;
var finalUrl = url.replace('_documentId_', id);
</script>

"_documentId_" is essentially a dummy placeholder. Then inside my JavaScript, I replace "_documentId_" with the proper id value once I know what it is. This way, regardless of how your route is configured, your URL will conform.


Update: Dec 20

I just saw this interesting blog post. The author built a library that allows you to build routes inside of your JavaScript file with intellisense support in VisualStudio.

http://weblogs.asp.net/zowens/archive/2010/12/20/asp-net-mvc-javascript-routing.aspx

like image 151
Johnny Oshika Avatar answered Nov 15 '22 04:11

Johnny Oshika


Personally I use unobtrusive javascript and avoid mixing markup with javascript. AJAX calls are normally triggered by clicking on some buttons or links:

@Html.ActionLink("click me", "List", "Objects", 
    new { area = "Reading", documentId = 3 }, new { id = "foo" })

and then in a separate js file I would attach and handle the onclick event (example with jquery):

$(function() {
    $('#foo').click(function() {
        $('#resultDiv').load(this.href);
        return false;    
    });
});

As you can I didn't need to use any hardcoded URL in my javascript file. URLs should always be handled by the routing engine and generated with html helpers.

If it was a <form> instead of a link I would simply handle the onsubmit event (the same way) and use the form's action attribute to get the URL.


UPDATE:

After pointing out in the comments section that the documentId is known only at client-side you could do this:

@Html.ActionLink("click me", "List", "Objects", 
    new { area = "Reading" }, new { id = "foo" })

And then:

$(function() {
    $('#foo').click(function() {
        $('#resultDiv').load(this.href, { documentId: '123' });
        return false;    
    });
});
like image 29
Darin Dimitrov Avatar answered Nov 15 '22 05:11

Darin Dimitrov