Lately i was trying to bring in some angular.js magic to one of the asp.net mvc project i was working on and ran into a strange situation.

I had my asp.net mvc action method returns the razor view if it is a normal request and JSON data if it is an ajax request. so my code goes like this.

if (Request.IsAjaxRequest())
{                
    List<IssueVM> issues = issueService.GetIssueListVMs(size);
    return Json(issues, JsonRequestBehavior.AllowGet);
}
else
{
    IssueListVM issueListVM = new IssueListVM();
    issueListVM = GetIssueListVM(size);              
    return View("List", issueListVM);
}

While debugging, i noticed that ,for the asynchronous calls made using  angular's $http service, it is not going inside my if condition because Request.IsAjaxRequest() method is returning false.  I tried a normal jQuery $.get method and it worked fine!  So there is obviously some difference between these two xhr calls.

I inspected the request headers of both the calls  using firebug and figured out what was missing in the call made by $http service.

angular-http-request-header-comparison

We are missing one header item called X-Requested-With in the xhr call initiated by angular's $http service. In ASP.NET MVC, the Request.IsAjaxRequest() method looks for this particular header value to determine whether the incoming request is an ajax request or not.  Some research about this behaviour took me to the angularjs github repository where they clearly mentioned this in one of their commits.

https://github.com/angular/angular.js/commit/3a75b1124d062f64093a90b26630938558909e8d

So the solution is to add ourselves this particular header to the calls made by our angular module.

var issuesApp = angular.module('issueListApp', []);

issuesApp.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
}]);

issuesApp.controller('IssuestCtrl', function ($scope, $http) {

    $http.get('../issues').success(function (data) {
        $scope.issuesList = data;
    });

});

This fixes the issue and now the Request.IsAjaxRequest() method returns true for those calls made using $http service.