Calling Cross Domain WCF service using Jquery/Javascript

About: This post is about to call “cross domain WCF Service” from your HTML page i.e. Calling WCF Service hosted on one domain and calling the service from other HTML page or hosted on other domain.

Following is the list of steps which needs to be follow.

Step1: To start first create New Solution and Add new project which is “WCF Service”

Step2: Rename your default interface name “IService1” to “IUser” and default service class name “Service1” to “UserService”.

Add following methods

Step3: Add these methods in your “IUser” interface.

[ServiceContract]
public interface IUser
{
[OperationContract]
[WebGet(UriTemplate = "GetUsers", ResponseFormat = WebMessageFormat.Json)]
List<User> GetUsers();

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
User InsertUser(User user);

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
bool DeleteUser(int userId);

}


“User” class.

[DataContract]
public class User
{
[DataMember]
public int UserId { get; set; }

[DataMember]
public string UserName { get; set; }

[DataMember]
public string Password { get; set; }
}

UserService.svc.cs

Step4: Implement you “IUser” interface in “UserService.svc”

For database connectivity I used EDMX and here is my context object.

private SampleEntities db = new SampleEntities();

Function 1: Implement GET method to fetch the users.

public List<User> GetUsers()
{
return db.Users.ToList();
}

This is my get method which returns the entire user.

Function 2: Implement POST method to add/insert the new user.

public User InsertUser(User user)
{
db.Users.Add(user);
db.SaveChanges();
return user;
}

This is my POST method which takes one argument as User, and we add it into our Users Table.

Function 3: Implement POST method to delete the existing user.

public bool DeleteUser(int userId)
{
var user = db.Users.Find(userId);
if (user != null)
{
db.Users.Remove(user);
db.SaveChanges();
return true;
}
else
return false;
}

This is my POST method which takes one argument as “userId” in form of integer, and the “remove” is delete that user from database.

Function 4: Implement POST method to update the existing user information.

public bool UpdateUser(User user)
{
var _user = db.Users.Find(user.UserId);
if (_user != null)
{
_user.UserName = user.UserName;
_user.Password = user.Password;
db.SaveChanges();
return true;
}
else
return false;
}

This is my POST method which takes one argument as User, and updates the user information in database.

Step5: Make sure that you added

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 

on your UserService class to make it compatible with other application.

Step6: After implementing this we need to update/configure settings of our Web.Config file. Bellow is the web.config file.

<system.serviceModel>
<services>
<service name="MyService.UserService">
<endpoint binding="webHttpBinding" contract="MyService.IUser" behaviorConfiguration="webHttp" bindingConfiguration="BasicAuthentication" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>;
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->;
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>;
<!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->;
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" crossDomainScriptAccessEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>

Note: This is Wcf Service Application normally we define our “End point” in our consumer config but here we are using cross domain and there might be no configuration file as in this application. So, we will define our “Endpoint” in the wcf service. For cross domain access we need to enable

crossDomainScriptAccessEnabled=”true”;

Step7: We need to add this code in our Global.asax file.

protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader(“Access-Control-Allow-Origin”, “*”);
if (HttpContext.Current.Request.HttpMethod == “OPTIONS”)
{
HttpContext.Current.Response.AddHeader(“Cache-Control”, “no-cache”);
HttpContext.Current.Response.AddHeader(“Access-Control-Allow-Methods”, “GET, POST, OPTIONS”);
HttpContext.Current.Response.AddHeader(“Access-Control-Allow-Headers”, “Content-Type, Authorization, Accept”);
HttpContext.Current.Response.AddHeader(“Access-Control-Max-Age”, “1728000”);
HttpContext.Current.Response.End();
}
}

We can defile this setting in Web.Config file also.

Step8: Now we are ready to consume our service in our application I have one html saved in my disc with named is “CallWCFService.html” which contains the design as well as javascript/jQuery code to call wcf service.

<body>
<form id=”myForm”>
<table border=”0″ width=”50%” cellspacing=”0″ cellpadding=”10″>
<tr>
<td colspan=”2″>
<div id=”dvMessage” style=”background-color: #f8efa7; box-shadow: 0 1px 2px rgba(0,0,0,0.15); border-radius: 3px; line-height: 1.5; width: 100%; position: relative; opacity: 1; z-index: -9000; text-align: center”></div>
</td>
</tr>
<tr>
<td colspan=”2″>
<h2>Existing Users</h2>
<div id=”dvUsers”>
</div>
</td>
</tr>
<tr>
<td colspan=”2″>
<h2>Insert User</h2>
</td>
</tr>
<tr>
<td><strong>User Name:</strong></td>
<td>
<input type=”text” title=”Enter User Name” id=”txtUserName”>
<span title=”Enter User Name”>ABC</span>
</td>
</tr>
<tr>
<td><strong>Password:</strong></td>
<td>
<input type=”password” id=”txtPass”></td>
</tr>
<tr>
<td colspan=”2″ align=”center”>
<input type=”button” id=”btnSubmit” value=”Add”>
</td>
</tr>
</table>
</form>
</body>

Step9: Bellow is my <script></script> which contains the jQuery/javascript code in order to call the WCF cross domain service.

To call Function 1:

$.ajax({
type: “GET”,
url: ‘http://localhost/MyService/UserService.svc/GetUsers&#8217;,
contentType: “application/json; charset=utf-8”,
dataType: “json”,
success: function (result) {
var list = “<table width=’50%’ border=’0′ cellspacing=’0′ cellpadding=’0′>”;
$.each(result, function (i, item) {
list+=”<tr onclick=\”FillRecord(“+item.UserId+”,'”+item.UserName+”‘,'”+item.Password+”‘)\” style=\”cursor:pointer;\” id=\”row”+item.UserId+”\”>”;                    list += “<td>” + item.UserId + “</td>”;
list += “<td>” + item.UserName + “</td>”;
list += “<td>” + item.Password + “</td>”;
list += “<td> <span title=\”Delete User\” onclick=\”deleteUser(” + item.UserId + “)\” style=\”cursor:pointer; color:blue;\” id=’spDel” + item.UserId + “‘>X</span></td>”;
list += “</tr>”;
});
list += “</table>”;
},
error: function (errMessage) {
alert(‘error ocured:’ + errMessage.status);
}
});

function FillRecord(userId, userName, password) {
$(“#hdnUserId”).val(userId);
$(“#txtUserName”).val(userName);
$(“#txtPass”).val(password);
}

This method is used to fill the selected records in the textbox.
To call Function 2:

$(“#btnSubmit”).click(function () {
var userInsert = { “UserId”: 0, “UserName”: $(“#txtUserName”).val(), “Password”: $(“#txtPass”).val() };
$.ajax({
type: “POST”,
data: JSON.stringify({ user: userInsert }),
url: ‘http://localhost/MyService/UserService.svc/InsertUser&#8217;,
contentType: “application/json; charset=utf-8”,
dataType: “json”,
success: function (result) {
$(“#dvMessage”).html(“User has been added successfully.!!”);
setTimeout(function () { $(“#dvMessage”).hide(); }, 5000);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(“ERROR” + xhr.status + ” + xhr.responseText + ” + thrownError);
}
});
});

JSON.stringify() is Browser method to parse data in JSON.
To call Function 3:

function deleteUser(userId) {
$.ajax({
type: “POST”,
data: JSON.stringify({ userId: userId }),
url: ‘http://localhost/MyService/UserService.svc/DeleteUser&#8217;,
contentType: “application/json; charset=utf-8”,
dataType: “json”,
success: function (result) {
$(“#dvMessage”).html(“User has been deleted successfully.!!”);
setTimeout(function () { $(“#dvMessage”).hide(); }, 5000);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(“ERROR” + xhr.status + ” + xhr.responseText + ” + thrownError);
}
});
}

This method is called in “To call Function 1:“code.
To call Function 4:

$(“#btnUpdate”).click(function () {
var userInsert = { “UserId”: $(“#hdnUserId”).val(), “UserName”: $(“#txtUserName”).val(), “Password”: $(“#txtPass”).val() };
$.ajax({
type: “POST”,
data: JSON.stringify({ user: userInsert }),
url: ‘http://localhost/MyService/UserService.svc/UpdateUser&#8217;,
contentType: “application/json; charset=utf-8”,
dataType: “json”,
success: function (result) {
$(“#dvMessage”).html(“User has been updated successfully.!!”);
setTimeout(function () { $(“#dvMessage”).hide(); }, 5000);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(“ERROR” + xhr.status + ” + xhr.responseText + ” + thrownError);
}});
});

 

Summary:

In this article I tried to explain and implement the cross domain wcf service with CRUD example. I hope after reading this article you will be able to call cross domain wcf service. I would like to have feedback and question from my blog reads, please post your comment and question in order to make it more useful. You can download code from here WCF Cross Domain Sample.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s