0

Question:

What is a clear, safe and systematic way to call my MVC controllers/actions from JavaScript, but keep the related URLs in a central place for updating when controllers change? Or to dynamically generate the URLs at run-time? Or to get compile-time checking for AJAX controller linkage?

Research/Past Attempts:

I've recently plugged in T4MVC to my MVC project. Great! Compile-time checking for controller linkage in my views - but I still have controller URLs littered all over my JavaScript. Worse, I have evolved how I do it over the project lifetime, so I do it multiple ways that I'm still not satisfied with.


1) One way:

locationAutoComplete = new AjaxQueue({
 Controller: "Utilities", // null for current controller
 Action: "GetMatchingLocations",
 DataModel: null, // null for raw JSON, or a local model to populate
 MaxQueuedRequests: 0
});

2) Another way:

locationAutoComplete = function (location) {
 return $.ajaxPost(resolveUrl("~/Utilities/GetMatchingLocations"));
}

3) Both 1 and 2 above make use of a project root defined in a Master/Layout JavaScript snippet, but still use unchecked URL strings. So now I've started benefiting from T4MVC by simply defining controller strings in my .CSHTML view:

var locationLookupController = @Url.Action(MVC.Utilities.GetMatchingLocations());

4) The SO article ( Ajax call Into MVC Controller- Url Issue ) addresses this a little. It talks about method 3, but also suggests using the AjaxHelper namespace. Since I make heavy use of jQuery AJAX with some pretty customized interactions (e.g. loading results into a local data model, not at a click event but at a timed interval), I don't think it will help me much. Today I don't even include the MS AJAX JavaScript code on any of my pages.

Thanks!

Community
  • 1
  • 1
shannon
  • 8,664
  • 5
  • 44
  • 74

1 Answers1

1

Continue to use T4MVC. Mix it in with a little jQuery and HTML5 data-* attributes. Here's an example:

<div data-location-lookup-url="@Url.Action(MVC.Utilities.GetMatchingLocations())">

...

locationAutoComplete = function (location) {
    var url = $('[data-location-lookup-url]').data('location-lookup-url');
    return $.ajaxPost(url);
}
danludwig
  • 46,965
  • 25
  • 159
  • 237
  • That's a great idea. It's better than putting anchor tags on my page that aren't meant to be used, but still is relatively compliant. I can create a helper for it... How do you get the URLs organized at the client? Currently I define all my controller URLs at one spot, specifically because of my maintenance problem. But like this... maybe the controllers should be defined on elements that use them. And do you write out each of your function definitions, or do you iterate a selected result with other attributes and create them? Do you store post vs. get in the DATA as well? So many questions :) – shannon Jun 27 '12 at 13:02
  • "...maybe the controllers should be defined on elements that use them." Yes. As for everything else, it depends. – danludwig Jun 27 '12 at 13:06
  • I can imagine I would replace my PostalCode template editor with one that includes a DATA attribute for the controller to do autocomplete. So many possibilities! – shannon Jun 27 '12 at 13:07