Hi my post explains how to call web service frm java script using AJAX.
If
the web service class on the server includes a web method that does not
return data, you can call the web service without having to handle a
response. This is the simplest web method call that can be made from
the client. For example, your application has the following web method:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public void NoReturn()
{
//do work here
System.Threading.Thread.Sleep(2000);
}
}
The following JavaScript can be used to invoke that web method
function RunWebService()
{
Parts.NoReturn();
}
If the webservice is in a custom namespace, you would need to fully
qualify the call to the webservice. For example, if the WebService
has a namespace of MyCustomNameSpace.WebServices, the above JavaScript
becomes:
function RunWebService()
{
MyCustomNameSpace.WebServices.Parts.NoReturn();
}
Getting a return value
In
a scenario where the web method has a return value, then the
asynchronous invocation model requires providing a callback function
that will be called when the web service call returns. The callback
function has an input parameter that contains the results of the web
service call.
The server-side AJAX stack will appropriately
serialize the return value from the web method, and the client-side
AJAX stack will deserialize the data to an appropriate JavaScript type
to be passed to the callback function.
On the Server-side, there is a WebMethod that returns a string:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public string DynamicDropdown()
{
string tmpDropDown;
tmpDropDown
= "<select id=test name=test><option
value=Part1>Part1</option><option
value=Part2>Part2</option></select>";
return tmpDropDown;
}
}
When
you call the web service in client script, the call will need to have a
callback function specified to handle the return value. The following
script demonstrates calling the DynamicDropdown WebMethod of the Parts
Web Service and specifies OnComplete as the callback function. The
OnComplete function has an input paramter which is the return object
from the web service call, in this case, this will be the string value.
The OnComplete function then takes the return value and inserts it as
the innerHTML property of a span with ID DynamicArea. The result is
that a dropdown appears on the page.
function InsertDropdown()
{
Parts.DynamicDropdown(OnComplete);
return false;
}
function OnComplete(result)
{
DynamicArea.innerHTML += result;
}
Passing primitive type parameters to web method
If
the web method takes input parameters, then the JavaScript invocation
of the method will take corresponding JavaScript parameters. The
parameter values will be serialized by the AJAX stack into JSON and
packaged in the body of the request and then de-serialized as .Net
types corresponding to the signature of the web method.
For example, given the following server method that accepts a string parameter and returns a string:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public string EchoString(String s)
{
return s;
}
}
You would use the following JavaScript to call the web service, pass the string parameter and include the callback function:
function CallEchoString()
{
Parts.EchoString(form1.GetString.value, OnCallBack);
}
function OnCallBack(results)
{
alert(results);
}
The
call to the EchoString web method on the Parts.asmx web service is
taking the value from a textbox named GetString in a form with ID of
“form1” to pass as the input parameter and specifying OnCallBack as the
callback function. The OnCallBack function has an input parameter of
“results” which is the return type from the EchoString web method. The
JavaScript then displays that in a popup box.
Specifying a callback for failure cases
If
the request to the web method is unsuccessful, whether because of
error, timeout, or if server code aborts the request, then the callback
specified for successful completion will not be called. A second
callback function can be specified in the call to the web service for
failure cases, receiving an error object as parameter, as in the
following javascript:
function CallService()
{
PeopleServices.ThrowError(OnCallBackThrowError, OnError);
}
function OnCallBackThrowError(result)
{
alert("OnCallbackThrowError: " + result);
}
function OnError(result)
{
alert("OnError: " + result.get_message());
alert(result.get_stackTrace());
}
In
the code sample, the ThrowError method of the PeopleServices web
service does not take any input parameters. The method call passes the
callback function “OnCallBackThrowError” and a method for handling any
error condition called “OnError”. The OnError method takes an input
parameter which is a error object that contains the error message and
stack information passed from the server if a .NET Exception was
thrown. In this case, the information is displayed in popup windows,
but once you have the errors in the browser, you can notify the user in
any manner you feel is appropriate.
Using the same callback from multiple callers
You
can leverage the same callback function on the client for multiple web
service calls. This allows you to avoid having to write a client
function for each callback. In order to differentiate the calls, you
pass a user context object that contains information that can be used
to tell the requests apart. The user context object can be any
JavaScript primitive type, array, or object.
For example,
let’s say you have a web service that contains a web method that you
need to call multiple times from the client. You need to know which
response corresponds to each call. For example, the first call’s return
value is placed in Span1 and the second call is in Span2. In order to
do this, you can associate context information with the request and you
can use the context information to distinguish which request is
providing the response. This information is not passed to the server by
default. If you want to pass this information to the web service, you
would need to pass it as an input parameter to the remote method.
On
the server, you have the following web service method that is taking in
the a string which should be a stock symbol and returning a string:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public string UserContextSample(string stockSymbol)
{
string returnValue = String.Empty;
//do work here to look up stock symbol info
return returnValue;
}
}
On
the client, you create a JavaScript object to store context specific
information and pass that as the last parameter to the web service
call. In the sample below, we’re creating a dictionary object on the
client with a key of contextKey and a value of a stock quote. The
syntax for the web service call is:
WebService.Method(InputParams, CallBackMethod, ErrorMethod, contextInfo);
function CallServicesTest()
{
var userContext1 = {contextKey:"MSFT"};
Parts.UserContextSample("MSFT", OnCallBack, OnError, userContext1);
var userContext2 = {contextKey:"AAPL"};
Parts.UserContextSample("AAPL", OnCallBack, OnError, userContext2);
}
In
the callback function, you add a second input parameter that contains
the context passed in the web service call. This way you get the
results of the web service call in the first input parameter and the
context information in the second parameter. In this case, we’re
checking the context information and inserting text into specific spans
on the page along with the response from the web service.
function OnCallBack(results, userContext)
{
switch(userContext.contextKey)
{
case "MSFT":
SPAN1.innerHTML = "Microsoft " + results;
break;
case "AAPL":
SPAN2.innerHTML = "Apple " + results;
break;
}
}
Using the same callback for different web methods
This
scenario is similar to using the same callback for multiple calls with
the exception that you have two separate web service methods on the
client that are using the same callback method. In this scenario, you
include a third input parameter on the callback function to receive the
web service call that the response is associated to.
For
example, you have two Web Methods that your function needs to call, but
you want to have a single callback method. You can tell which web
method is returning by accessing the optional third input parameter to
the callback function.
On the server you have:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class Parts : System.Web.Services.WebService
{
[WebMethod]
public string EchoString(String s)
{
return s;
}
[WebMethod]
public string AnotherEchoString(String s)
{
return s;
}
}
On the client you have a button that has an onclick method calling GetEcho() function in JavaScript:
function GetEcho()
{
Parts.EchoString("This is echo number 1", OnCallBack);
Parts.AnotherEchoString("Another echo string!", OnCallBack);
}
function OnCallBack(results, userContext, sender)
{
alert(results + "\n" + sender);
}
When
OnCallBack runs, you will get an alert dialog with the string you
passed to the web service along with Parts.EchoString or
Parts.AnotherEchoString.
Passing and receiving a server type
As
mentioned previously, the AJAX networking stack will generate proxy
scripts for any server type that is referenced as an input or output
parameter by the web methods contained in linked web services. This
allows a developer to access these types on the client in a similar
fashion as they would on the server. The types are serialized using
JSON serialization which is covered in the next lesson.
For
example, let’s say you have the following web service called
PeopleServices. This web service has a method called NewPerson that
takes in 3 parameters; 2 Person objects and 1 object of type bool. The
return value is also of type Person.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Microsoft.Web.Script.Services.ScriptService]
public class PeopleServices : System.Web.Services.WebService
{
[WebMethod]
public Person NewPerson(Person parent1, Person parent2, bool female)
{
Person _newPerson = new Person();
//Do other work
return _newPerson;
}
}
When
you add this web service to the ScriptManager, the client will make a
request for the proxy script as discussed in the Proxy Generation
section. The result is that the Proxy script will have the web service
method as well as the properties for the Person class. The person class
is defined as the following on the server:
public class Person
{
public string Name
{
get { return _name; }
set { _name = value; }
}
public int Age
{
get { return _age; }
set { _age = value; }
}
public int Height
{
get { return _height; }
set { _height = value; }
}
}
On
the client, you would need to generate two objects of type Person and
pass them as parameters to the web service. In the callback script, the
result parameter will be of type Person. Here’s a sample JavaScript
function that takes the values of textboxes on the page and creates two
Person objects, then calls the NewPerson object on the above web
service.
function GetNewPerson()
{
var person1 = new Person();
var _name = document.getElementById('p1FirstName');
var _age = document.getElementById('p1Age');
var _height = document.getElementById('p1Height');
person1.Name = _name.value;
person1.Age = _age.value;
person1.Height = _height.value;
var person2 = new Person();
_name = document.getElementById('p2FirstName');
_age = document.getElementById('p2Age');
_height = document.getElementById('p2Height');
person2.Name = _name.value;
person2.Age = _age.value;
person2.Height = _height.value;
PeopleServices.NewPerson(person1, person2, true, OnCallbackGetNewPerson, OnError);
}
Here
is a sample callback function that handles the return type from the
NewPerson method. The result parameter is a Person object and you can
directly access the properties. In this case NewPerson is the ID on a
Div in the page.
function OnCallbackGetNewPerson(result)
{
var newPerson = result;
NewPerson.innerHTML = "New Person <br/>";
NewPerson.innerHTML += "Name: " + newPerson.Name + "<br />";
NewPerson.innerHTML += "Age: " + newPerson.Age + "<br />";
NewPerson.innerHTML += "Height: " + newPerson.Height + "<br />";
}
When you run pages that make these calls and check out the network traffic, you’ll see the following:
Web
service call is a POST to …/PeopleService.asmx/js/NewPerson. Since the
request ends in /js/NewPerson, the AJAX HttpHandler will handle the
request to the web service. The Content-Type of the request is
application/json.
Request Body contains all the data to create the
Person object on the server. The main piece is the __type parameter
which tells the server what type to create:
{"parent1":{"__type":"Person","Name":"Name1","Age":"12","Height":"60"},"parent2":{"__type":"Person","Name":"Name2","Age":"24","Height":"72"},"female":true}
The
response also has a Content-Type of application/json and has a similar
body containing the __type parameter and values necessary to create the
Person object on the client:
{"__type":"Person","Name":"Name1name2ella","Age":23,"Height":71}
Demo is FireForgetDemo.aspx
Hope my post help you.