Web API With AJAX: Cross Domain AJAX Call With GET Request

In this article we will learn one very practical and important concept of AJAX implementation using Web-API.

This is the "Web API with AJAX" article series. In this series we are talking about AJAX associated with the Web API that is nothing but the latest communication technology in Microsoft's platform. We have completed a very important explanation regarding this topic. You can read them here.

In this article we will learn one very practical and important concept of an AJAX implementation using the Web API. We know that modern web applications can be consumed by various types of clients from a smart phone to a black and white console application. And basically, the clients might expected the data to be formatted differently. And here is the advantage of the Web API. It supports smart content negotiation. Now, people usually host their application in various remote servers and the client runs in a totally separate box (let's assume a Desktop computer). Now when the user or client makes a request to this API via some other code, them there is a chance for a "Cross-domain" request. So, the general concept is the service application and logic will be hosted in a different domain. The advantage is that the actual program may crash whereas the Web API will still be alive. But the big problem is that we cannot make a cross-domain request in a normal way using the ajax() function. We need to set permission in the Web API. In this article we will learn to configure a cross-domain request.

Implement client to make Cross-domain request


Here is the AJAX implementation to make a code request. Have a look at the ajax() function . We have set the crossDomain = true. That implies that this ajax() function is allowed to make a Cross-domain request.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="callAJAX.aspx.cs" Inherits="clientProject.callAJAX" %>

<head runat="server">

    <script src="JQuery.js" type="text/javascript"></script>

 

    <script>

        $(document).ready(function () {

            $("#Save").click(function () {

                $.ajax({

                    url: 'http://localhost:3413/api/person',

                    type: 'GET',

                    dataType: 'json',

                    crossDomain: true,

                    success: function (data, textStatus, xhr) {

                        console.log(data);

                    },

                    error: function (xhr, textStatus, errorThrown) {

                        console.log(errorThrown);

                    }

                });

 

            });

        });

    </script>

 

</head>

<body>

    <form id="form1" runat="server">

        <input type="button" id="Save" value="Save Data" />

    </form>

</body>

</html>

So, this is the implementation of the ajax() function and now we will implement Web API that will run in a separate project. So, to make a Cross-domain request we need to run the client and API in an entirely separate project.

Implement Web API to accept Get() request

In this example we will implement a simple Web API to accept a Get() request. We are just returning a string value from the Get() method. Here is the sample implementation.
 

using System;

using System.Collections.Generic;

using System.Collections.Specialized;

using System.Linq;

using System.Net;

using System.Net.Http;

using System.Net.Http.Formatting;

using System.Web.Http;

 

namespace WebApplication1.WebAPI

{

 

    public class personController : ApiController

    {

        [HttpGet]

        public string Get()

        {

            return "Response From CROSS domain";

        }

    }

}

Configure CrosHandler to allow Cross-domain request

Now we need to configure CrosHandler to handle the Cross-domain request. Use one class file and put the following code into it.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Net.Http;

using System.Threading;

using System.Threading.Tasks;

using System.Web;

 

namespace WebApplication1

{

    public class CorsHandler : DelegatingHandler

    {

        const string Origin = "Origin";

        const string AccessControlRequestMethod = "Access-Control-Request-Method";

        const string AccessControlRequestHeaders = "Access-Control-Request-Headers";

        const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";

        const string AccessControlAllowMethods = "Access-Control-Allow-Methods";

        const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

 

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

        {

            bool isCorsRequest = request.Headers.Contains(Origin);

            bool isPreflightRequest = request.Method == HttpMethod.Options;

            if (isCorsRequest)

            {

                if (isPreflightRequest)

                {

                    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

                    response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

 

                    string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();

                    if (accessControlRequestMethod != null)

                    {

                        response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);

                    }

 

                    string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));

                    if (!string.IsNullOrEmpty(requestedHeaders))

                    {

                        response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);

                    }

 

                    TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();

                    tcs.SetResult(response);

                    return tcs.Task;

                }

                else

                {

                    return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>

                    {

                        HttpResponseMessage resp = t.Result;

                        resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

                        return resp;

                    });

                }

            }

            else

            {

                return base.SendAsync(request, cancellationToken);

            }

        }

    }

}

The understanding of the code above is beyond the scope of this article. The ultimate goal of this code is to allow a Cross-domain request in the Web API.

Register crossdomain in Application_Srart() event

Open the global.aspx page in the Web API application and use the following line in the Application_Start() event of the page.

//register cors handler

GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());

Now we have successfully set up the Web API to allow the Cross-domain request. Here is sample output.

Cross domain AJAX call with GET request

Conclusion

In this example we have learned to implement a Cross-domain setup and call the Web API to use the GET method. Hope you have understood it. In my next article we will learn to make a POST request using a Cross-domain request. Happy coding.