Why ASP.NET MVC Request.IsAjaxRequest method returns false for $http calls from angular
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.
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.