Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Calling ASP.NET Web API service in a cross domain using jQuery ajax

Suggested Videos
Part 11 - ASP.NET Web API query string parameters
Part 12 - FromBody and FromUri in Web API
Part 13 - Call ASP.NET Web API from jQuery

In this video we will discuss, how to call an ASP.NET Web API service in a cross domain using jQuery ajax. This is continuation to Part 13, please watch Part 13 from ASP.NET Web API tutorial before proceeding.



What is same origin policy
Browsers allow a web page to make AJAX requests only with in the same domain. Browser security prevents a web page from making AJAX requests to another domain. This is called same origin policy.



The following 2 URLs have the same origin
http://localhost:1234/api/employees
http://localhost:1234/Employees.html

The following 2 URLs have different origins, because they have different port numbers (1234 v/s 5678)
http://localhost:1234/api/employees
http://localhost:5678/Employees.html

The following 2 URLs have different origins, because they have different domains (.com v/s .net)
http://pragimtech.com/api/employees
http://pragimtech.net/Employees.html

The following 2 URLs have different origins, because they have different schemes (http v/s https)
https://pragimtech.com/api/employees
http://pragimtech.net/Employees.html

To prove browsers does not allow cross domain ajax requests, let's add a new web forms project to EmployeeService solution. Name it ClientApplication. Add an HTML page. Name it HtmlPage1.html. Copy and paste the following HTML and jQuery code.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="Scripts/jquery-1.10.2.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            var ulEmployees = $('#ulEmployees');

            $('#btn').click(function () {
                $.ajax({
                    type: 'GET',
                    // Make sure to change the port number to
                    // where you have the employee service
                    // running on your local machine
                    url: 'http://localhost:23258/api/Employees',
                    dataType: 'json',
                    success: function (data) {
                        ulEmployees.empty();
                        $.each(data, function (index, val) {
                            var fullName = val.FirstName + ' ' + val.LastName;
                            ulEmployees.append('<li>' + fullName + '</li>')
                        });
                    }
                });
            });

            $('#btnClear').click(function () {
                ulEmployees.empty();
            });
        });
    </script>
</head>
<body>
    <input id="btn" type="button" value="Get All Employees" />
    <input id="btnClear" type="button" value="Clear" />
    <ul id="ulEmployees"></ul>
</body>
</html>

When you click "Get All Employees" button on "HtmlPage1.html" page, you get the following error. To see the error launch browser tools and click on the console tab.
XMLHttpRequest cannot load http://localhost:23258/api/Employees. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:6293' is therefore not allowed access.

On the other hand when you click "Get All Employees" button on "Employees.html" page that is present in the same project as the ASP.NET Web API Service, that employee data is displayed without any problem.

So this proves, browsers does not allow cross domain ajax requests. There are 2 ways to get around this problem
  • Using JSONP (JSON with Padding) 
  • Enabling CORS (Cross Origin Resource Sharing)
In this video let's use JSONP to overcome the browser cross-domain restriction. In our next video we will discuss enabling CORS. 

So what is JSONP and what does it do?
JSONP stands for JSON with Padding. All JSONP does is wraps the data in a function. So for example, if you have the following JSON object
{
    "FirstName" : "Mark",
    "LastName"  : "Hastings",
    "Gender"    : "Male",
}

JSONP will wrap the data in a function as shown below
CallbackFunction({
    "FirstName" : "Mark",
    "LastName"  : "Hastings",
    "Gender"    : "Male",
})

Browsers allow to consume JavaScript that is present in a different domain but not data. Since the data is wrapped in a JavaScript function, this can be consumed by a web page that is present in a different domain.

Steps to make ASP.NET Web API Service to return JSONP formatted data and consume it from a cross domain ajax request
Step 1 : To support JSONP format, execute the following command using NuGet Package Manager Console which installs WebApiContrib.Formatting.Jsonp package.
Install-Package WebApiContrib.Formatting.Jsonp

Step 2 : Include the following 2 lines of code in Register() method of WebApiConfig class in WebApiConfig.cs file in App_Start folder

var jsonpFormatter = new JsonpMediaTypeFormatter(config.Formatters.JsonFormatter);
config.Formatters.Insert(0, jsonpFormatter);

Step 3 : In the ClientApplication, set the dataType option of the jQuery ajax function to jsonp 
dataType: 'jsonp'

Testing the ASP.NET Web API Service using fiddler
Notice in fiddler we have just specified the URL of the Web API service without Accept header and callback function in the URI
asp.net web api jsonp example

The above request results in the following error
A callback parameter was not provided in the request URI

If you want JSON data back, set Accept header to application/json and there is no need to specify the callback function in the URI. The request completes successfully.
asp.net web api crossdomain

If you want JSONP formatted data back, set Accept header to application/javascript and specify a name for the callback function in the URI. We have set it to ABC.
asp.net web api ajax cross domain

ASP.NET Web API tutorial for beginners

12 comments:

  1. Hi Venkat.

    I am getting this error : "Attempt by security transparent method 'System.Web.Http.GlobalConfiguration.get_Configuration()' to access security critical type 'System.Web.Http.HttpConfiguration' failed."

    while trying to call service cross domain.

    ReplyDelete
  2. It resolved by installing 'Install-Package Microsoft.AspNet.WebApi -IncludePrerelease'

    ReplyDelete
  3. it have error of cross domain remains it is not working properly error at run time resolve it plz

    ReplyDelete
  4. Hi, Is Cross Domain issue is a browser specific one? The data is not displayed on Chrome but worked fine in IE with out CORS or JasoP for me?

    ReplyDelete
  5. hi sir, my case is totally different. I created a different html page and saved it in my local disk. and when I tried to test that, I got totally surprised that It still working fine even without configuring it with jsonp.

    ReplyDelete
  6. Jsonp works well with get can you Show an Example of Post request Also.

    ReplyDelete
  7. Jsonp works well with get can you Show an Example of Post,Put and Delete request Also.

    ReplyDelete
  8. It works fine for me on "Visual Studio Express 2015 for Web".

    ReplyDelete
    Replies
    1. If I have used Tools -> Nuget Package Manager -> Package Manager Console to install "WebApiContrib.Formatting.Jsonp" package, then it gets installed but error(type or namespace name could not found) showing on this line ->"using WebApiContrib.Formatting.Jsonp;".

      If I use Tools -> Nuget Package Manager -> Manage Nuget Packages for Solution... to install "WebApiContrib.Formatting.Jsonp" package, then it gets installed & error will also not comming.

      Delete
  9. I get the below error, what to do?

    The name 'JsonpMediaTypeFormatter' does not exist in the current context
    The name 'jsonpFormatter' does not exist in the current context

    ReplyDelete
  10. Severity Code Description Project File Line Suppression State
    Error CS0122 'JsonMediaTypeFormatter.JsonMediaTypeFormatter(JsonMediaTypeFormatter)' is inaccessible due to its protection level WebApiDemo

    ReplyDelete
  11. JsonMediaTypeFormatter.JsonMediaTypeFormatter(JsonMediaTypeFormatter)' is inaccessible due to its protection level

    ReplyDelete

It would be great if you can help share these free resources