Frequently I see devs needing to make calls into C# controllers and return some data to the front end. The most common tool I’ve seen these devs reach for is the jQuery $ajax wrapper.

I asked the question: “Can this be done without jQuery?” And, overwhelmingly, the answer I got back was no. I didn’t think that made a lot of sense since jQuery is really just using JavaScript under the hood. So it would seem that you must be able to achieve this with plain old js.

After a bit more digging, I found that it is possible. Here’s how:

Let’s assume we have Hello World being sent to us from the controller, and then we want to show it in an alert. Our front end won’t know what is going to be displayed until it is returned from the controller. Our controller method might look like this:

  [HttpGet]
  public ActionResult RespondToAjax()
  {
      return Json("Hello World!", JsonRequestBehavior.AllowGet);
  }

Things to note here are that we’ve added the [HttpGet] decorator above our method, thus denoting that this is a get and not a post. Also, with the JSON string we’re returning, we added JsonRequestBehavior.AllowGet. Without this you’ll get an error because MVC doesn’t just allow gets willy-nilly.

Our js function might look like this:

function callCtrler() {
    var req = new XMLHttpRequest();
    req.open('GET', '@Url.Action("RespondToAjax", "Home")', true);
    req.setRequestHeader('Content-Type', 'application/json');

    req.onload = function () {
        if (req.status >= 200 && req.status < 400) {
            alert(req.responseText);
        } else {
            alert('We encountered an error!');
        }
    }

    req.send();
}

One thing I want to note here is that we are using razor with @Url.Action. It’s important to use @Url.Action over a relative path (./file/path/) because relative paths won’t always work in MVC. Using the above method won’t allow you to move your javascript into its own file. However, you can attach the @Url.Action to an element with a data attribute and access it that way.

<form id="myForm" data-ctrl-url='@Url.Action("RespondToAjax", "Home")'></form>

Then in your JavaScript you can use:

var ctrlUrl = document.getElementById('myForm').getAttribute('data-ctrl-url');

Now let’s look at how we might do a POST. We’ll need both a controller method and a class this time.

[HttpPost]
public ActionResult PostFromAjax(TestModel postParams)
{
    // do something with data, probably create db record
    return Json("Success!");
}

public class TestModel
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string FavoriteColor { get; set; }
}

We have our action method using [HttpPost] as the decorator this time. This allows us to post to the method. We also created a class for the data. You aren’t able to use built in types such as Dictionary or object, so you’ll need to create a custom class for the data to map to.

Now let’s take a look at what the js function looks like.

function postToCtrl() {
    var tmpObj = {
        Name: 'Carmen',
        Age: 26,
        FavoriteColor: 'Green'
    };

    var req = new XMLHttpRequest();
    req.open('POST', '@Url.Action("PostFromAjax", "Home")', true);
    req.setRequestHeader('Content-Type', 'application/json');
    req.send(JSON.stringify(tmpObj));
}

Notice we made an object with the exact same properties as our class – this allows the data to be mapped to the class properly. We also stringified the data before sending it across.

And there you have it! GET and POST to C# methods without jQuery!

Checkout the test app I made for this.

Questions? Tweet me!