In one of my projects,I was facing an issue where I need to save data on one of my User Controls which was
loaded dynamically.The problem was as soon I click the save button,page gets postback and User Control was
unloaded,so unable to save data.Then I check for various solutions where I found one which was to call service
methods from client side.It is fairly simple approach.Here in the demo I am using, has 4 projects as under
1)Business Logic-where I have written my methods to save or retrieve data.
2)Model-where my data model is placed
3)Wcf Service-where I am going to call methods in business logic
4)Web-where I will consume the services.
Business Logic
Here is the code in my business logic , where I have added 4 methods.I have added custom object which
is having same properties as in Testimonial object(which is in Model) as it was unable to serialize the class in
Model.The significance of first method i.e public CustomObj GetNewTestimonial() is we have to first pass to
the client, the object type we are going to serialize to JSON(which takes key value pairs,seperated by comma).
You will see on .aspx page where I have called this method before any other to make sure that our object
(CustomObj) gets serialize to JSON.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Client_Model;
using Client_Model.EntityModel;
namespace Client_BusinessLogic
{
public class Client_Testimonial {
public CustomObj GetNewTestimonial()
{
return new CustomObj();
}
public List<CustomObj> GetAllTestimonial()
{
using (var context= new ClientEntities())
{
List<CustomObj> listTestimonial= new List<CustomObj>();
var result = (from t in context.Testimonials select t).ToList();
foreach (var testimonial in result)
{
var obj = new CustomObj {
CountryId = testimonial.CountryId,
FirstName = testimonial.FirstName,
LastName = testimonial.LastName
};
listTestimonial.Add(obj);
}
return listTestimonial;
}
}
public bool SaveTestimonial(CustomObj test)
{
using (var context= new ClientEntities())
{
var obj = new Testimonial();
obj.FirstName = test.FirstName;
obj.LastName = test.LastName;
obj.CountryId = test.CountryId;
obj.Desciption = test.Description;
obj.InstanceId = 1;
obj.IsDeleted = true;
obj.IsArchive = test.IsArchive;
context.AddToTestimonials(obj);
context.SaveChanges();
return true;
}
}
public CustomObj GetMyRecords(int id)
{
using (var context = new ClientEntities())
{
var result = (from a in context.Testimonials
where a.TestimonialId == id
select new CustomObj { CountryId = a.CountryId, FirstName = a.FirstName,
LastName = a.LastName}).FirstOrDefault();
return result;
}
}
}
public class CustomObj {
public string FirstName { get; set; }
public string LastName { get; set; }
public string CountryId { get; set; }
public string Description { get; set; }
public bool IsArchive { get; set; }
}
}
Wcf Service
Now in wcf service we will call these methods ,but few things to keep in mind which are
1)References :System.ServiceModel,System.ServiceModel.Activation
2)Add these tags before your class name :
[ServiceContract(Namespace = "TestimonialJsonService")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
The “TestimonialJsonService” is the name we will use to call this service from client side.
3) Add this tag before your methods you want to expose at client side.
[WebGet(ResponseFormat = WebMessageFormat.Json)]
This will parse object to be returned to JSON Format.
4)Changes you have to make in web .config or app.config of WCF service project
a)Add the following line of code under
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<standardEndpoints>
<webScriptEndpoint>
<standardEndpoint name="" crossDomainScriptAccessEnabled="true" /> </webScriptEndpoint> </standardEndpoints>
</system.serviceModel>
b)Set
<system.web>
<authentication mode="None"/>
</system.web>
5)Open .svc file markup and add
<%@ ServiceHost Language="C#" Debug="true" Service="Client_Service.Service.TestimonialService"
CodeBehind="TestimonialService.svc.cs" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"%>
The code under is my Service class file where I am just calling the methods from business logic.
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using Client_BusinessLogic;
using Client_Model.EntityModel;
using System.Runtime.Serialization;
namespace Client_Service.Service
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "TestimonialService"
in code, svc and config file together. [ServiceContract(Namespace = "TestimonialJsonService")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TestimonialService {
public void DoWork()
{
}
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public CustomObj GetNewTestimonial()
{
return new CustomObj();
}
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public List<CustomObj> GetAllTestimonial()
{
var client = new Client_Testimonial();
var result = client.GetAllTestimonial();
return result;
}
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public bool SaveTestimonial(CustomObj test)
{
var client = new Client_Testimonial();
bool result = client.SaveTestimonial(test);
return result;
}
}
}
Web Project
The first thing which we will do is to add the connection string to web.config of the .web project if it is not there.

Now in all we are left with code on our aspx page ,in my case I have done it in default.aspx page.
Do read the comments mentioned in coding
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="ClientSideCall._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
var proxy = null;
var jsonObj = null;
//This method is called on page load .Here we are instantiating our proxy object to point to our service
//"TestimonialJsonService" is the name we have mentioned in Service Contract in WcfService class
//(check point-2 in Wcf Service mentioned above) and "TestimonialService" is the class name of WcfService
function makeCall() {
proxy = new TestimonialJsonService.TestimonialService;
proxy.set_enableJsonp(true);
proxy.GetNewTestimonial(onSuccess, onFail, null);
//GetNewTestimonial is the first method coded in Wcfservice class .
//By default this method will contain three parameters.
}
//this is called if object returend above is serialized successfully
function onSuccess(result, usercontext, methodname) {
alert("success");
jsonObj = result;
}
// This function is called if the service call fails
function onFail(error, usercontext, methodname) {
alert("error");
}
//This method is set to call on ButtonClick .Here i have used the ClientId of the controls to get their value
function save() {
$(document).ready(function () {
var value = $('input:radio[name$="<%=IsArchive.ClientID %>"]:checked');
var result1 = value.val();
jsonObj.FirstName = document.getElementById("txtFirst").value;
jsonObj.LastName = document.getElementById("txtLast").value;
jsonObj.CountryId = document.getElementById("txtCountryId").value;
jsonObj.Description = document.getElementById("txtDescription").value;
jsonObj.IsArchive = result1;
//SaveTestimonial is method that will save the above values in say Testimonial table in Db.
//here jsonObj is like CustomObj in service call
//If you have to send more than one parameter,add them here only separated by comma
proxy.SaveTestimonial(jsonObj, save_onSuccess, save_onFail, null);
});
}
function save_onSuccess(result)
{
alert(" Data Save Succesfully");
}
function save_onFail()
{
alert("Error Saving Data");
}
</script>
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:ScriptManager runat="server" ID="SM1">
<Services> <%--this is the url where our service is running --%>
<asp:ServiceReference Path="http://localhost:1231/Service/TestimonialService.svc" />
</Services>
</asp:ScriptManager>
<asp:RadioButtonList ID="IsArchive" runat="server" ClientIDMode="Static">
<asp:ListItem Text="True" Value="1" ></asp:ListItem>
<asp:ListItem Text="false" Value="0" Selected="True"></asp:ListItem>
</asp:RadioButtonList>
FirstName:<asp:TextBox ID="txtFirst" runat="server" ClientIDMode="Static"></asp:TextBox>
LastName:<asp:TextBox ID="txtLast" runat="server" ClientIDMode="Static"></asp:TextBox>
Description:<asp:TextBox ID="txtDescription" runat="server" ClientIDMode="Static"></asp:TextBox>
CountryId:<asp:TextBox ID="txtCountryId" runat="server" ClientIDMode="Static"></asp:TextBox>
<%--We have used html buttom to avoid postback or else we can use OnClientClick of some server button--%>
<button type="button" id="btnSave" onclick="save();return false;" >Click Me!</button>
<%-- We will call the method makecall before any other methods so to serialize the object before--%>
<script type="text/javascript" defer="defer">makeCall();</script>
</asp:Content>
I have attached a sample app.Kindly change connection string before you run it.
ClientSideCall.zip (181.65 kb)