Make
Script based web service which could be called by JavaScript
I
remember the days when I need to call web service from JavaScript using some
HTML component called webservice.htc. It was a pain to consume web service
using that component as compare to current solution provided by Asp.net Ajax
team of Microsoft. I must say, Hats off to Microsoft for making life easier of
the developers of their technologies. Following are few factors for using
“calling web service from JavaScript”.
When
you need to:
- Call web
server and perform some operation on server like updating database or some
File I/O operations or have to queue the requests and have less to do on
client side like just need to show Operation completed or data based
updated.
- Send request
to web server asynchronously and don’t want to put user on wait for
completion of request
- Perform
operation on server side more efficiently as you wont follow page life
cycle
When
you don’t need to:
- Initiate Page
object and/or need to follow page life cycle
- Post back page
and Render page automatically
- Send request
to web server synchronously and put user on wait of completion of
processing
- Submit form
- Use cache,
session or need to access any asp.net intrinsic object
Aforementioned
points tells simply, when to call web service from JavaScript and when not.
I
would like to create some scenarios before digging into implementation steps to
clearer need of this technique.
Let’s
suppose,
- You need to
delete/update some record from your database and need to show “Record
deleted/updated” kind of message at browser after operation.
- You need to
check weather of some place by sending zip or name of place.
- Check login credential
(username/password) for validity
- If user forgot
his/her password then email his/her password
- Validate
Credit card or any such card information only
These
were some tasks, which we normally do in our web sites on regular basis but we
do such tasks normally on button click and have to initiate page object and
follow the whole page life cycle unnecessarily most of the time. As I have
mentioned in asp.net chapter all the stages/events of asp.net page life cycle,
which could cause performance bottleneck if doesn’t required.
Implementation
I
would like to clear this concept by means of real time example, which we could
need or most probably have seen. Google Auto Suggest or Yahoo Search box, you
can get such textbox at numerous web sites now.
When
you press any key in textbox, it will list down all the words/phrases which
start from that key(s). Isn’t it cool?
Pseudo code
- Put
ScriptManager control and Textbox control on web form
- Create web
service and web method which will return list against keys user pressed
· Web method should be attributed by [System.Web.Script.Services.ScriptService()] to be called by javasacript through ScriptManager
- Associate web
service by ScriptManger control
- Call web
method from javascript using web service class name
- Create method
to get result of web method after completion as it’s asynchronous
communication
Sample code
Aspx/html sample
code
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Auto Suggest Example Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1"runat="server">
<Services> <%--Associate web service with our
Script manager--%>
<asp:ServiceReference Path="Autosuggest.asmx"/>
</Services>
</asp:ScriptManager>
<input id="txtSuggest"type="text"onkeyup="CallWebService(this.value);"/> </form>
</body>
</html>
ASMX
Web service, C# code
[WebService(Namespace
= "http://AutosuggestSample.org/")]
[WebServiceBinding(ConformsTo
= WsiProfiles.BasicProfile1_1)]
public class Autosuggest : System.Web.Services.WebService {
public Autosuggest () {
//constructor
}
[WebMethod]
[System.Web.Script.Services.ScriptService()]
public string
Suggest(char key) {
//On the basis
of key which user press in Textbox and
//Transmit to web service as parameter
//we are sending back relevant word (can send multiple
words/phrases as well)
//so to keep it simple, i 'm just sending back single word
for few keys
switch (key)
{
case "A":
return "Apple";
break;
case "B":
return "Ball";
break;
case "C":
return "Cat";
break;
case "D":
return "Doll";
break;
default:
return "No
suggestion in dictionary against this " + key.ToString();
}
}
}
JavaScript Code
<script type="text/javascript">
function CallWebService(txtValue)
{
//Call web service's web method
Autosuggest.Suggest(txtValue, OnComplete, OnError, OnTimeOut)
//Autosuggest is class/instance name of web service
//Suggest is web
method
//txtValue is parameter required by our web method
//OnComplete is delegate to completion method, would be
called automatically
//after web method completion
//OnError is delegate to completion method, would be called
automatically
//on error in web method execution
//OnTimeOut is delegate to completion method, would be
called automatically
//if web service doesn't response in specified time
}
function OnComplete(arg)
{
//arg is return value from web method
document.getElementById('txtSuggest').value
= arg;
}
function OnTimeOut(arg)
{
alert("TimeOut encountered");
}
function OnError(arg)
{
alert("Error : " + arg);
}
</script>
Implementation wise, its
not full fledge sample code of Auto suggest textbox. Implementation code is
just to give an idea about “calling web service from javascript”, so to keep
example simple, I just tried to simplify auto suggest code.
Conclusion
This
approach is great, when developer is enough eligible to handle request and
response objects and yes good in javascript as well. This approach is faster
than asp.net callback, page methods and typical AJAX technique, let me tell you
how, suppose there are 30 controls on your web page and you have written some
code in page_init and page_load or any of them so to perform just a little
operation like checking credentials of user in db to see whether user is valid
or not, if you use asp.net AJAAX or asp.net callback techniques, 30 controls
holder page instance would be created and even page_init and page_load would
fire which is unnecessary in some situations but in case of calling some
webservice through javascript make more sense as it has only method which needs
to run and only that method would be call so unnecessary things.
Important Note
You cannot call web service which is lying on
any other domain, server or for easy understanding, you may say, out of your website
scope like suppose:
Your
website is www.abc.com and web service is
lying at www.xyz.com
So
according to my emails with Microsoft's
Opinionated Misfit Geek: Mr. Joe Stagner, a very helping guy,
Me:
Dear Joe,
Can you tell me, how can we call web service web method by (XMLHTTPRequest) XHR
if that web service is at another web server. I tried but get access is denied
:$ and not getting any solution on net. You are guru of gurus so expecting
solution from urself ;-) Please help
Thanks,
Joe:
You can’t – that’s the whole point of the browser’s cross domain
security policy.
So the solution was:
Joe:
You need to proxy the service you want from your own server
Me:
You mean I need to create classes/web service at local and
access web services through them?
That's what I was trying to avoid :(
Joe:
Yes
Hope you got good understanding
of this and will be able to utilize this technique in well manner.
Thanks,