This entry is to guide you through the transition from the page method to the script service. Don't worry it won't hurt a bit...
Using page methods is a great idea for getting more performance out of your ajax apps but if they have a few draw backs
- They don’t promote reusability, user controls methods would but sadly they missed the boat.
- Getting them to actually work on a hosted server is somewhat of a mistory (see: http://www.west-wind.com/WebLog/posts/152493.aspx)
The best thing about page methods is that the converted me to using Web Services or Script Services. Script services are regular web services with a few extra attributes. The good thing is that you can have a javascript proxy built for you just like a page method. Better still, the web service is actually usable from anywhere...
The hello world of the script service.
Fire up visual studio and start a new Web Project (or web site if you must) .
Add a new Web Service
The Hello world template should be already present, as below .... (I changed the method name to ‘Hello’ so it’s different from the class name)
/// <summary>The add a reference to the System.Web.Extensions library and add the script service attribute to the class as below.
/// Summary description for HelloWorld
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class HelloWorld : System.Web.Services.WebService
{
[WebMethod]
public string Hello()
{
return "Hello World";
}
}
using System;That’s it. Done. We have converted out web service into a script service. Now we will move onto the default.aspx file and consume our script service.
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Script.Services;
namespace ScriptServiceExample
{
/// <summary>
/// Summary description for HelloWorld
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class HelloWorld : System.Web.Services.WebService
{
[WebMethod]
public string Hello()
{
return "Hello World";
}
}
}
Firstly check you web.confg has the necessary handlers defined.
<httphandlers>Now, Add a ScriptManger to the page and define the script service as follows.
<remove verb="*" path="*.asmx">
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false">
<add verb="*" path="*.asmx" type="System.Web.Script.Services.ScriptHandlerFactory" validate="false">
</add>
</add></remove></httphandlers>
<asp:scriptmanager id="ScriptManager1" runat="server">The web page will compile and run at this stage but viewing a blank page less than impressive.
<services>
<asp:servicereference path="/HelloWorld.asmx">
</asp:servicereference>
</services>
</asp:scriptmanager>
If you got firebug or other means you can run the page and check that the following javascript is actually generated and linked to the page..
Type.registerNamespace('ScriptServiceExample');This will not work yet because the function is defined as “ScriptServiceExample.HelloWorld.Hello” but just to encapsulate this call I am going to add an helper javascript file called HelloWorldHelper.js
ScriptServiceExample.HelloWorld=function() {
ScriptServiceExample.HelloWorld.initializeBase(this);
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
ScriptServiceExample.HelloWorld.prototype={
Hello:function(succeededCallback, failedCallback, userContext) {
return this._invoke(ScriptServiceExample.HelloWorld.get_path(), 'Hello',false,{},succeededCallback,failedCallback,userContext); }}
ScriptServiceExample.HelloWorld.registerClass('ScriptServiceExample.HelloWorld',Sys.Net.WebServiceProxy);
ScriptServiceExample.HelloWorld._staticInstance = new ScriptServiceExample.HelloWorld();
ScriptServiceExample.HelloWorld.set_path = function(value) {
var e = Function._validateParams(arguments, [{name: 'path', type: String}]); if (e) throw e; ScriptServiceExample.HelloWorld._staticInstance._path = value; }
ScriptServiceExample.HelloWorld.get_path = function() { return ScriptServiceExample.HelloWorld._staticInstance._path; }
ScriptServiceExample.HelloWorld.set_timeout = function(value) { var e = Function._validateParams(arguments, [{name: 'timeout', type: Number}]); if (e) throw e; if (value < _timeout =" value;" get_timeout =" function()" set_defaultusercontext =" function(value)" _usercontext =" value;" get_defaultusercontext =" function()" set_defaultsucceededcallback =" function(value)" e =" Function._validateParams(arguments," _succeeded =" value;" get_defaultsucceededcallback =" function()" set_defaultfailedcallback =" function(value)" e =" Function._validateParams(arguments," _failed =" value;" get_defaultfailedcallback =" function()" hello=" function(onSuccess,onFailed,userContext)" href="http://www.blogger.com/post-edit.g?blogID=3340352991227979961&postID=790319424207465397">Ping the server
The final html looks like this..
<form id="form1" runat="server">NB: You should move the script include into the head of your document
<div>
<asp:scriptmanager id="ScriptManager1" runat="server">
<services>
<asp:servicereference path="/HelloWorld.asmx">
</asp:servicereference>
</services>
<script src="helloWorldHelper.js" type="text/javascript"></script>
<a href="javascript: Hello()">Ping the server</a>
</asp:scriptmanager><div id="processing" style="display: none;">
fetching
</div>
<div id="results">
</div>
</div>
</form>
The javascript file looks like this..
function Hello()
{
$get('processing').style.display = 'block';
ScriptServiceExample.HelloWorld.Hello(SuccessCallBack);
}
function SuccessCallBack(result)
{
$get('results').innerHTML = result;
$get('processing').style.display = 'none';
}
That’s it, consuming your script service couldn’t be easier.
Sending complex results to your web page is as easy as returning an object from your web service. The object will automatically be serilised using JSON (although you can specify XML if you want).
Quick code for returning an object.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class HelloWorld : System.Web.Services.WebService
{
[WebMethod]
public HelloWorldResponse Hello()
{
HelloWorldResponse r = new HelloWorldResponse();
r.Message = "Hello World";
r.Time = DateTime.Now;
return r;
}
}
[Serializable]
public class HelloWorldResponse
{
public string Message;
public DateTime Time;
}
Comsuming the object, client side
function Hello()
{
$get('processing').style.display = 'block';
ScriptServiceExample.HelloWorld.Hello(SuccessCallBack);
}
function SuccessCallBack(result)
{
var resultObject = eval(result)
$get('results').innerHTML = "The Message is:" + resultObject.Message + " The message was created on " + resultObject.Time;
$get('processing').style.display = 'none';
}
4 comments:
Interesting to know.
my onsuccess method is not called.. Could you please help me out.
I've downloaded your sample code and if I use the Visual Studio Development Server, it works fine, but if I use IIS then I get a JS error on clicking the link:
'ScriptServiceExample' is undefined.
Can you please advise? I need it to work in IIS. Many thanks.
keep up the good work! this blog is really interesting and gives good details.
Thanks...
Mechanical Seals
Post a Comment