Calling cross domain WCF services using Jquery



Author : Ashish Dwivedi (dwivedi.animesh@gmail.com)


Whenever we try to call a cross domain WCF Service by javascript or jquery, it behaves differently with different browsers. When we want to perform "POST" or "GET" request on cross domain wcf service or normal service using jquery/javascript or ajax, the browser actually sends an "OPTIONS" verb call to wcf service that is not mention in wcf method attribute. We mention there "POST" or "GET" to call a wcf service method. Hence we get error to call cross domain wcf service. I found the following request and response headers in firefox when I tried to call wcf service.

Request Headers

OPTIONS http://myserver/MyService.svc/GetStates HTTP/1.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5

Response Headers

HTTP/1.0 405 Method Not Allowed
Cache-Control: private
Allow: POST
Content-Length: 1565
Content-Type: text/html; charset=UTF-8

In above request headers the method is "OPTION" not "POST" and the response headers has content-type "text/html; charset=UTF-8" instead of "json;charset=UTF-8". To change these options we need to do some changes in web.config of hosted wcf service.

Configure WCF Cross Domain service

namespace CrossDomainWcfService 
 { 
 [DataContract] 
 public class Supplier 
 { 
 [DataMember] public string Name;
 [DataMember] public string Email; 
 }
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsModeAspNetCompatibilityRequirementsMode.Allowed)]
public class MyService
 {
 [OperationContract]
 [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat =             WebMessageFormat.Json)]
  Public List GetSuppliers (int OrgID)
    { 
      // Fetch data from database
  var q= (from tbl in mobjentity.Customer  where tbl.OrgID=OrgID).ToList();
  Listlst= new List();
  foreach(var supp in q)
  {
  Supplier msupp=new Supplier();
  msupp.Name=supp.Name;
  msupp.Email=supp.Email
 //Make Supplier List to retun
  lst.Add(msupp);
   }
  return lst;
  } 
 } 
}

WCF Service Web.config

<system.webServer>
 <modules runAllManagedModulesForAllRequests="true" />
 <httpProtocol>
 <customHeaders>
 <add name="Access-Control-Allow-Origin" value="*" />
 <add name="Access-Control-Allow-Headers" value="Content-Type" /> 
 </customHeaders>
 </httpProtocol> 
</system.webServer>
 <system.serviceModel>
 <behaviors>
</behaviors>
 <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
 <standardEndpoints>
 <webScriptEndpoint>
 <standardEndpoint name="" crossDomainScriptAccessEnabled="true" />
 </webScriptEndpoint>
 </standardEndpoints>
 <services>
</service> 
</services> 
<bindings> 
</bindings> 
<client> 
</client>
</system.serviceModel>

Global.asax Code

We can also define hosted service web.config setting in Global.asax file. If we have defined setting in web.config then there is no need to do here.
protected void Application_BeginRequest(object sender, EventArgs e)
{
 HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin" , ”*”);
 if (HttpContext.Current.Request.HttpMethod == "OPTIONS" )
 { 
 //These headers are handling the "pre-flight" OPTIONS call sent by the browser 
  HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods" , "GET, POST" );
  HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers","Content-Type, Accept");
 HttpContext.Current.Response.AddHeader("Access-Control-Max-Age" "1728000" );
  HttpContext.Current.Response.End();
} 
} 

WCF calling using Jquery

$.ajax({ 
type: "Post"
url: "http://www.yourdomain.com/MyService.svc/GetSuppliers", // Location of the service
data: '{"OrgID"="1"}', //Data sent to server
contentType: "application/json;charset-uf8", // content type sent to server
dataType: "json", //Expected data format from server
success: function (msg) {
//Implement get data from service as you wish
},
error: function (err) {
// When Service call fails
}
});

Note:

We can define cross domain setting either in web.config or in global.asax file of wcf service. Summary:
In this article I tried to explain cross domain wcf service calling with example. I hope after reading this article we will be able to call cross domain wcf service.

For any query / sugegstions please feel free to mail author Ashish Dwivedi at dwivedi.animesh@gmail.com (dwivedi [dot] animesh [at] gmail[dot] com )

Comments