Introduction
This blog focuses on calling a WCF service in a cross domain environment. To elaborate it, let us say the WCF service is hosted in a domain called http://wcf.com and the client application that requires to call the WCF service is hosted in a domain called http://client.com. Cross domain interaction between web resources has been a challenge as far as client scripting like Javascript, flush and others are concerned.
This blog provides a downloadable solution, links for further reading and a bit of explanation about some important web configuration sections and service properties.
JSON with Padding (JSONP)
JSONP is a complement to the JSON data format. The JSONP format enables a page to request data from a server in a different domain. See useful references.
The downloadable solution uses the JSONP format to make requests to the WCF service hosted in a different domain. The Jquery library supports the JSONP format requests in its $.ajax() and $.getJSON() methods. Later in this blog, there will be examples for both Jquery methods.
The WCF Service
The example WCF service is designed to return a list of customers when its GetCustomer method has been called. Key properties are highlighted.
.Net Framework 4 and Visual Studio 2010 are both required to compile the solution.
Service Designer (.svc)
<%@ServiceHost
language="c#"
Debug="true"
Service="Microsoft.Samples.Jsonp.CustomerService"
Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"
%>
Service Class (.cs)
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Collections.Generic;
namespace Microsoft
.Samples.Jsonp
{
[DataContract
]
public class Customer
{
[DataMember
]
public string FirstName
;
[DataMember
]
public string LastName
;
}
[ServiceContract
(Namespace="JsonpAjaxService")]
[AspNetCompatibilityRequirements
(RequirementsMode
= AspNetCompatibilityRequirementsMode
.Allowed)]
public class CustomerService
{
[WebGet
( BodyStyle
=WebMessageBodyStyle
.Bare, ResponseFormat
= WebMessageFormat
.Json)]
public List
<Customer
> GetCustomer
()
{
List
<Customer
> list
= new List
<Customer
>();
list
.Add(new Customer
() { FirstName
="Nathan", LastName
="Abebe"});
list
.Add(new Customer
() { FirstName
= "Dawit", LastName
= "Yitagesu" });
return list
;
}
}
}
Web.Config
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP"
crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="Microsoft.Samples.Jsonp.CustomerService">
<endpoint address="" behaviorConfiguration="webHttpBehavior"
binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJsonP"
contract="Microsoft.Samples.Jsonp.CustomerService" />
</service>
</services>
</system.serviceModel>
The Client (Javascript)
var Type;
var Url;
var Data;
var ContentType;
var DataType;
var ProcessData;
var method;
//Call service static class
function CallService() {
$.ajax({
type: Type, //GET or POST or PUT or DELETE verb
url: Url, // Absolute location of the service
data: Data, //Data sent to server (Example {APIKey: 'your api key'})
contentType: ContentType, // content type sent to server
dataType: DataType, //Expected data format from server
processdata: ProcessData, //True or False
success: function (msg) {//On Successful response
ServiceSucceeded(msg);
},
error: ServiceFailed// On Unsuccessful response
});
}
function ServiceFailed(xhr) {
alert(xhr.responseText);
if (xhr.responseText) {
var err = xhr.responseText;
if (err)
error(err);
else
error({ Message: "Unknown server error." })
}
return;
}
function ServiceSucceeded(data) {
if (DataType == "jsonp") {
$.each(data, function () {
var string = this.FirstName + " \n " + this.LastName;
alert(string);
});
}
}
//Url is consisted of {domain}/{service file}/{method name}
//assuming the serivce file is found in the application root folder
function getCustomerByJqueryAjax() {
Type = "GET";
Url = "http://localhost:33695/service.svc/GetCustomer";
DataType = "jsonp";
ProcessData = false;
method = "GetCustomer";
CallService();
}
//Url is consited of {domain}/{service file}/{mothod name}{?callback=?}
//assuming the serivce file is found in the application root folder
function ajaxJsonPost() {
$.getJSON("http://localhost:33695/service.svc/GetCustomer?callback=?",
function (data) {
$.each(data, function (index, item) {
alert(item.FirstName + ' ' + item.LastName);
});
});
}
$(document).ready(function () {
getCustomerByJqueryAjax();
getCustomerByJqueryGetJson();
});
Useful References
Windows Communication Foundation Sample Solution Downloads
JSONP for cross-site Callbacks
What is JSONP