ASP.NET MVC URLs for Knockout (and other MV-something Javascript Frameworks)

Here’s a way to pass ASP.NET MVC URLs to your Knockout models from an ASP.NET MVC application via HTML configuration instead of global Javascript variables. It also works with any of the other MV-something Javascript frameworks, like AngularJS, and plain Javascript. The key here is the Javascript does not have to know how to build MVC URLs. Instead, MVC is used to configure the URL that is used by Javascript.

First the view:

<div id="myForm" data-search-url='@Url.Action("Action", "Controller", new {area="optionalArea"})'>
<!-- form with bindings to the Knockout model -->
</div>

Here’s an AJAX post:

$.ajax({
  type: "POST",
  url: $("#myform").data("search-url"),
  contentType: 'application/json; charset=utf-8',
  //postData is a Javascript object with properties matching those of the .NET objet
  data: ko.toJSON(postData),
  success: function (data) {
    //handle response
  }
  error: function(xhr, ajaxOptions, thrownError) {
    //error handling
  }
});

If the MVC route expects parameters in the query string, an AJAX get is also straightforward:

$.ajax({
  type: "GET",
  url: $("#myform").data("search-url"),
  contentType: 'application/json; charset=utf-8',
  //query string here is ?name1=value1&name2=value2
  data: {name1: value1, name2: value2},
  success: function (data) {
    //handle response
  }
  error: function(xhr, ajaxOptions, thrownError) {
    //error handling
  }
});

You can also handle more complex routing schemes by putting placeholders in the data attribute on the view side and using replace on the Javascript side to set the parameters. For example, imagine we want a URL like “/area/controller/action/{id}”. In that case, the view would look like this:

<div id="myForm" data-search-url='@Url.Action("Action", "Controller", new {area="optionalArea", id="_id_"})'>
<!-- form with bindings to the Knockout model -->
</div>

And the AJAX call:

$.ajax({
  type: "GET",
  url: $("#myform").data("search-url").replace("_id_", idFromModel),
  contentType: 'application/json; charset=utf-8',
  success: function (data) {
    //handle response
  }
  error: function(xhr, ajaxOptions, thrownError) {
    //error handling
  }
});

The beauty of this approach is it relies completely on MVC for the format of the URL. There are absolutely no assumptions in the Javascript about the routing scheme.