<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.alexthissen.nl/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Alex Thissen Weblog Build 1.15.10.1971 : AJAX</title><link>http://www.alexthissen.nl/blogs/main/archive/tags/AJAX/default.aspx</link><description>Tags: AJAX</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Combining AJAX and WCF 2.0</title><link>http://www.alexthissen.nl/blogs/main/archive/2008/03/22/combining-ajax-and-wcf-2-0.aspx</link><pubDate>Fri, 21 Mar 2008 20:36:47 GMT</pubDate><guid isPermaLink="false">badf6229-ffeb-484a-8c5a-fc9c9987c8f2:2881</guid><dc:creator>Alex Thissen</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.alexthissen.nl/blogs/main/rsscomments.aspx?PostID=2881</wfw:commentRss><comments>http://www.alexthissen.nl/blogs/main/archive/2008/03/22/combining-ajax-and-wcf-2-0.aspx#comments</comments><description>&lt;p&gt;The WCF &amp;quot;Orcas&amp;quot; release (the WCF from .NET Framework 3.5 aka WCF 2.0) makes it so much easier to use your WCF service in conjunction with ASP.NET AJAX (formerly known as 'Atlas'). &lt;/p&gt;  &lt;p&gt;Before Orcas you would build a AJAX enabled (web) service by adding the [ScriptService] attribute to the service class.&lt;/p&gt;  &lt;div style="border-right:#cccccc 1pt solid;padding-right:1pt;border-top:#cccccc 1pt solid;padding-left:1pt;font-size:10pt;background:#f5f5f5;padding-bottom:1pt;border-left:#cccccc 1pt solid;width:100%;color:black;padding-top:1pt;border-bottom:#cccccc 1pt solid;font-family:consolas;"&gt;   &lt;p style="margin:0px;"&gt;[&lt;span style="color:#2b91af;"&gt;WebService&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;strong&gt;[&lt;span style="color:#2b91af;"&gt;ScriptService&lt;/span&gt;]&lt;/strong&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;{&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:green;"&gt;// Implementation details&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;}&lt;/p&gt; &lt;/div&gt;   &lt;p&gt;The ScriptServiceAttribute enables you to reference a JavaScript proxy from your client-side JS by including &lt;/p&gt;  &lt;div style="border-right:#cccccc 1pt solid;padding-right:1pt;border-top:#cccccc 1pt solid;padding-left:1pt;font-size:10pt;background:#f5f5f5;padding-bottom:1pt;border-left:#cccccc 1pt solid;width:100%;color:black;padding-top:1pt;border-bottom:#cccccc 1pt solid;font-family:consolas;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;script&lt;/span&gt; &lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://.../AlmostCoolestService.asmx/js&amp;quot;&lt;/span&gt; &lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;   &lt;p&gt;Notice the /js that is appended at the end. That bit is the work of the ScriptService attribute. You do not have to add the script element manually, but get that automatically when you add a service reference to the ScriptManager control in your page.&lt;/p&gt;  &lt;p&gt;Before anything will work all .asmx requests in an AJAX-enabled website are redirected to a different handler:&lt;/p&gt;  &lt;div style="border-right:#cccccc 1pt solid;padding-right:1pt;border-top:#cccccc 1pt solid;padding-left:1pt;font-size:10pt;background:#f5f5f5;padding-bottom:1pt;border-left:#cccccc 1pt solid;width:100%;color:black;padding-top:1pt;border-bottom:#cccccc 1pt solid;font-family:consolas;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.web&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;httpHandlers&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;remove&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;verb&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;*&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;path&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;*.asmx&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;add&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;verb&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;*&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;path&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;*.asmx&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;validate&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;System.Web.Script.Services.ScriptHandlerFactory, ...&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;add&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;verb&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;*&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;path&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;*_AppService.axd&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;validate&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;...&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;add&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;verb&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;GET,HEAD&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;path&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;ScriptResource.axd&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;System.Web.Handlers.ScriptResourceHandler, ...&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;validate&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;false&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;httpHandlers&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.web&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This replacement .asmx handler will return JSON data instead of the usual SOAP enveloppes, allowing for easy usage from the JavaScript code.&lt;/p&gt;  &lt;p&gt;&amp;lt;Side.note&amp;gt;&lt;/p&gt;  &lt;p&gt;Here is a bit of JSON (JavaScript Object Notation) data:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="border-right:#cccccc 1pt solid;padding-right:1pt;border-top:#cccccc 1pt solid;padding-left:1pt;font-size:10pt;background:#f5f5f5;padding-bottom:1pt;border-left:#cccccc 1pt solid;width:100%;color:black;padding-top:1pt;border-bottom:#cccccc 1pt solid;font-family:consolas;"&gt;   &lt;p style="margin:0px;"&gt;{ &lt;span style="color:#a31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt; : &lt;span style="color:#a31515;"&gt;&amp;quot;Alex&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;Age&amp;quot;&lt;/span&gt; : 35 }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Did you know that this is actually just a JavaScript fragment? Take a look at this:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="border-right:#cccccc 1pt solid;padding-right:1pt;border-top:#cccccc 1pt solid;padding-left:1pt;font-size:10pt;background:#f5f5f5;padding-bottom:1pt;border-left:#cccccc 1pt solid;width:100%;color:black;padding-top:1pt;border-bottom:#cccccc 1pt solid;font-family:consolas;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; person = { &lt;span style="color:#a31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt; : &lt;span style="color:#a31515;"&gt;&amp;quot;Alex&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;Age&amp;quot;&lt;/span&gt; : 35 };&lt;/p&gt;    &lt;p style="margin:0px;"&gt;window.alert(person.Age);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;So, when you send some JSON data over the wire, it is very easy to start working with that data.&lt;/p&gt;  &lt;p&gt;&amp;lt;/Side.note&amp;gt;&lt;/p&gt;  &lt;p&gt;This is quite a bit of work, right?&lt;/p&gt;  &lt;p&gt;In Orcas we get support for JSON, URL parameters and non-SOAP XML. It also has Atlas-specific conventions such as the JavaScript proxy.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Support for calling WCF service from the client stack&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Visual Studio 2008 has WCF AJAX support, meaning that the ScriptManager understands these types of services and new templates like the AJAX-enabled WCF service. The latter will automaticaly create the correct configuration and corresponding skeleton code.&lt;/p&gt;  &lt;p&gt;Enabling a WCF service for AJAX is a decision you can make at deployment time. So, you can call into any regular WCF service from AJAX without making any changes to your implementation. You do need to make some changes, which vary based on your hosting scenario. &lt;/p&gt;  &lt;p&gt;Let's assume you have an IIS hosted WCF service. You need to edit the ServiceHost directive in the .svc file and specify a different ServiceHostFactory implementation, like so:&lt;/p&gt;  &lt;div style="border-right:#cccccc 1pt solid;padding-right:1pt;border-top:#cccccc 1pt solid;padding-left:1pt;font-size:10pt;background:#f5f5f5;padding-bottom:1pt;border-left:#cccccc 1pt solid;width:100%;color:black;padding-top:1pt;border-bottom:#cccccc 1pt solid;font-family:consolas;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="background:#ffee62;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;@&lt;/span&gt; &lt;span style="color:red;"&gt;ServiceHost&lt;/span&gt; &lt;span style="color:red;"&gt;Service&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;CoolestWCFService&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;Factory&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;WebScriptServiceHostFactory&amp;quot;&lt;/span&gt; &lt;span style="background:#ffee62;"&gt;%&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;   &lt;p&gt;Here WebScript actually means AJAX-enabled.&lt;/p&gt;  &lt;p&gt;When you host the WCF service yourself, you should edit your configuration file to enable JSON support.&lt;/p&gt;  &lt;div style="border-right:#cccccc 1pt solid;padding-right:1pt;border-top:#cccccc 1pt solid;padding-left:1pt;font-size:10pt;background:#f5f5f5;padding-bottom:1pt;border-left:#cccccc 1pt solid;width:100%;color:black;padding-top:1pt;border-bottom:#cccccc 1pt solid;font-family:lucida console;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;serviceHostingEnvironment&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;aspNetCompatibilityEnabled&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;services&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;service&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AjaxService&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpoint&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;address&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;behaviorConfiguration&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AjaxBehavior&lt;/span&gt;&amp;quot;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:red;"&gt;binding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;webHttpBinding&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;contract&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;IAjaxService&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;service&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;services&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpointBehaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behavior&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AjaxBehavior&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;enableWebScript&lt;/span&gt;&lt;span style="color:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behavior&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpointBehaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Note how you only need to add an endpoint behavior for enabling WebScript. This makes WCF do the same thing as ASMX web services: it can generate a JavaScript proxy when you visit the URL &lt;a href="http://.../CoolestWCFService.svc/js"&gt;http://.../CoolestWCFService.svc/js&lt;/a&gt;. BTW, the WebScriptServiceHost automatically adds this behavior to any endpoint that has a WebMessageEncodingBindingElement in its Binding element list, but does not have the WebHttp behavior defined. If you are interested in a little more on hosting, check &lt;a href="http://www.alexthissen.nl/blogs/main/archive/2007/07/10/orcas-web-programming.aspx"&gt;here&lt;/a&gt; (a bit dated, but still pretty much ok).&lt;/p&gt;  &lt;p&gt;So, why would you switch to WCF services instead of ASMX services?&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;The separation of contract and binding&lt;/strong&gt;:       &lt;br /&gt;Because the service contract and the binding are separated it will line you up better for future versions of encoding or . You will only need to change the configuration file to hook up e.g. some JSON version 2 (which might become reality to fix the recent security vulnerabilities in JSON v1). Or, you can add an application layer to expose the same service simultaneously as an AJAX and a SOAP service. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;The cool features of WCF&lt;/strong&gt;:       &lt;br /&gt;How are you going to protect your ASMX service from Denial of Service (DoS) attacks? In WCF you can protect your service with quotas, throttles and timeouts. There are more manageability options, such as logging, tracing and a whole bunch of performance counters. Think about the extra hosting options (e.g. self-hosted) for WCF services.       &lt;br /&gt;Also, Workflow Services in .NET 3.5 allow you to put a workflow inside a service which is behind an AJAX-enabled page. Compared to ASMX you could get performance gains as much as 4 times for large messages (rough estimate and preliminary results). And you get to use the HTTP programming model, such as POX and returning binary data. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;The DataContract data model:        &lt;br /&gt;&lt;/strong&gt;Going forward from .NET 3.0 the DataContract way of serializing is the preferred way. In 3.5 you may have noticed that Linq to SQL and ADO.NET Entities have built-in support for DataContract as well. The generated types for both Linq to SQL and ADO.NET Entities are [DataContract] types. Also, Linq to XML will have its XNode and derived types serialize to strings, so there is no problem to send them over the wire and use these in JavaScript. Furthermore, the DataContract is an opt-in model, so your type never gets serialized by accident. This is especially important, since you are sending the information to the browser client. The future directions of &amp;quot;Orcas+1&amp;quot; also indicate neat stuff to happen with the workflow data model and transformations (see &lt;a href="http://www.alexthissen.nl/blogs/main/archive/2007/04/11/more-on-orcas-1-release.aspx" target="_blank"&gt;this entry&lt;/a&gt; for a little more detail). &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;The future&lt;/strong&gt;: There has been no investment in new features for ASMX since .NET 2.0 or in Orcas. Will there be for the future? &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Finally, here are some characteristics of the WCF AJAX architecture:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Operation names are in the URL. There are no SOAP actions. A special operation dispatcher makes this happen. &lt;/li&gt;    &lt;li&gt;Parameters in URLs, because no message body is available for GET requests. Again, a special formatter will take care of that. &lt;/li&gt;    &lt;li&gt;JSON parameters in URLs (Atlas-specific) allows for complex types to be passed from the client to the service. &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://www.alexthissen.nl/aggbug.aspx?PostID=2881" width="1" height="1"&gt;</description><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Web+Services/default.aspx">Web Services</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/ASP.NET+2.0/default.aspx">ASP.NET 2.0</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/.NET+FX+3.5/default.aspx">.NET FX 3.5</category></item><item><title>IT-Boxing event in Sofia: the Bulgarian adventure</title><link>http://www.alexthissen.nl/blogs/main/archive/2008/03/10/it-boxing-event-in-sofia-the-bulgarian-adventure.aspx</link><pubDate>Mon, 10 Mar 2008 12:07:10 GMT</pubDate><guid isPermaLink="false">badf6229-ffeb-484a-8c5a-fc9c9987c8f2:2877</guid><dc:creator>Alex Thissen</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.alexthissen.nl/blogs/main/rsscomments.aspx?PostID=2877</wfw:commentRss><comments>http://www.alexthissen.nl/blogs/main/archive/2008/03/10/it-boxing-event-in-sofia-the-bulgarian-adventure.aspx#comments</comments><description>&lt;p&gt;&lt;img style="margin:0px 0px 0px 10px;" src="http://itboxing.devbg.org/wp-content/themes/itboxing/images/logo.png" align="right" /&gt;A couple of weeks ago I was invited to participate in the &lt;a href="http://itboxing.devbg.org/"&gt;IT-Boxing event&lt;/a&gt; that took place last thursday, March 6th in Sofia, Bulgaria. The IT-Boxing event is a one-night competition, organized by the &lt;a href="http://www.devbg.org/"&gt;Bulgarian Association of Software Developers&lt;/a&gt; (BASD), in which a couple of teams battle to be the best. Each of these competitions has a particular theme and the one in which I joined was &amp;quot;&lt;a href="http://itboxing.devbg.org/news/2007-12-19/second-it-boxing-match-web-development-technologies-aspnet-php-java-jsf-ruby-etc/"&gt;Web development platforms&lt;/a&gt;&amp;quot;. There were four teams representing Java (Echo2, Google Web Toolkit, Java Server Faces), PHP (Symphony), Ruby (on Rails) and ASP.NET. Each team is given a couple of timeslots of 20 minutes to demonstrate a particular part of their framework that would crush the opposition in features, demos, arguments, beauty and plain insults of the others. If arguments are not enough, you could always try to beat your opponent another way: with raw physical power. Check out the video of one of those fights (use the &lt;a href="http://www.youtube.com/watch?v=fR_OME_I2KE"&gt;YouTube version&lt;/a&gt; if SoapBox doesn't work for you).&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:02aa8964-aab1-4ca0-84ec-fc0e884e32c1" style="padding-right:0px;display:inline;padding-left:0px;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;div id="b283dee1-158a-4b66-ad5c-f5d5eb258877" style="margin:0px;padding:0px;display:inline;"&gt;&lt;div&gt;&lt;a href="http://video.msn.com/video.aspx?vid=eaac55f0-5305-4a5b-ba93-9ba98d7f5713&amp;amp;from=writer" target="_new"&gt;&lt;img src="http://www.alexthissen.nl/blogs/main/WindowsLiveWriter/ITBoxingeventinSofiatheBulgarianadventur_12C69/videoef835585d6da.jpg" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;&lt;em&gt;Note: no humans were hurt (badly) making this movie.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I got two out of three slots to show off the capabilities of ASP.NET AJAX and the ASP.NET MVC Framework (of course the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=38CC4CF1-773A-47E1-8125-BA3369BF54A3&amp;amp;displaylang=en"&gt;CTP2 version&lt;/a&gt; that was released just the day before at MIX08!). Emil Stoychev demo-ed the Dynamic data controls. We stomped the opposition with great arguments. A certain victory awaited us, or did it?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.alexthissen.nl/blogs/main/WindowsLiveWriter/ITBoxingeventinSofiatheBulgarianadventur_12C69/IMG_1811_2.jpg"&gt;&lt;img height="143" alt="LX in action" src="http://www.alexthissen.nl/blogs/main/WindowsLiveWriter/ITBoxingeventinSofiatheBulgarianadventur_12C69/IMG_1811_thumb.jpg" width="191" border="0" /&gt;&lt;/a&gt; &lt;a href="http://www.alexthissen.nl/blogs/main/WindowsLiveWriter/ITBoxingeventinSofiatheBulgarianadventur_12C69/IMG_1874_2.jpg"&gt;&lt;img height="143" alt="The audience are less violent than the teams" src="http://www.alexthissen.nl/blogs/main/WindowsLiveWriter/ITBoxingeventinSofiatheBulgarianadventur_12C69/IMG_1874_thumb.jpg" width="191" border="0" /&gt;&lt;/a&gt; &lt;a href="http://www.alexthissen.nl/blogs/main/WindowsLiveWriter/ITBoxingeventinSofiatheBulgarianadventur_12C69/IMG_1950_2.jpg"&gt;&lt;img height="143" alt="The .NET team is ready for battle" src="http://www.alexthissen.nl/blogs/main/WindowsLiveWriter/ITBoxingeventinSofiatheBulgarianadventur_12C69/IMG_1950_thumb.jpg" width="191" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Well, as it turned out the &lt;a href="http://itboxing.devbg.org/news/2008-03-08/java-won-the-second-it-boxing-match-on-web-technologies/"&gt;Java team won that night&lt;/a&gt;. Their main argument against ASP.NET was that the combination of Visual Studio and the ASP.NET framework was too much designer and clicking around to get things done. Java would allow (and need) you to write most code by hand, but that was &amp;quot;much more development at enterprise level&amp;quot;. Cheaters as they were (pun intended here), they pulled in the entire J2EE platform to show that Java development was the way for large enterprises. Their only &amp;quot;real&amp;quot; demo was a video of some Content Management System that was shown as a video, and a boring one at that. Sigh. During the discussion round we argued that we could show off products like BizTalk, SharePoint and the like, but that this was all about web development frameworks. Unfortunately, nearly all .NET devotees had gone home early, sure of the immense victory, only to make it a small one for the Java team. All-in-all around 150 votes (out of 300 attendees) were given: 79 for Java, 49 for ASP.NET, 13 or so for Ruby and 11 for PHP.&lt;/p&gt;  &lt;p&gt;Despite the loss I had so much fun on this event. It is a welcome change from the normal user group meetings with a vibrant, animated and fun format. To top, this one was cross-platform and therefore very educational for anyone that is mainly dedicated to a single platform. There are so many options, even for a single framework or platform. Call to Dutch user-group organizers: do a similar event in the Netherlands. Should be good fun. The event in Sofia got 300+ people to attend on a normal weekday evening. Nuff said.&lt;/p&gt;&lt;img src="http://www.alexthissen.nl/aggbug.aspx?PostID=2877" width="1" height="1"&gt;</description><enclosure url="http://www.alexthissen.nl/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.00.28.77/AjaxWebApplicationDemoITBoxing.zip" length="334049" type="application/x-zip-compressed" /><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Talks/default.aspx">Talks</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/ASP.NET+2.0/default.aspx">ASP.NET 2.0</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/.NET+FX+3.5/default.aspx">.NET FX 3.5</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/INETA/default.aspx">INETA</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Community/default.aspx">Community</category></item><item><title>Out with CAPTCHA, in with NoBot control</title><link>http://www.alexthissen.nl/blogs/main/archive/2006/12/02/out-with-captcha-in-with-nobot-control.aspx</link><pubDate>Sat, 02 Dec 2006 22:15:23 GMT</pubDate><guid isPermaLink="false">badf6229-ffeb-484a-8c5a-fc9c9987c8f2:2008</guid><dc:creator>Alex Thissen</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.alexthissen.nl/blogs/main/rsscomments.aspx?PostID=2008</wfw:commentRss><comments>http://www.alexthissen.nl/blogs/main/archive/2006/12/02/out-with-captcha-in-with-nobot-control.aspx#comments</comments><description>&lt;P&gt;It seems like almost everybody (including myself) was having big trouble getting a comment into my weblog. The main culprit was the &lt;A href="http://msdn2.microsoft.com/en-us/library/ms972952.aspx" target=_blank&gt;CAPTCHA control&lt;/A&gt; that I found on the &lt;A href="http://msdn.microsoft.com/" target=_blank&gt;MSDN site&lt;/A&gt;&amp;nbsp;and have been using since. It resulted not only in a lot of user unfriendliness, but also a lot of runtime errors (memory corruption :O ) and an unavailable weblog.&lt;/P&gt;
&lt;P&gt;So, out goes the CAPTCHA control. Welcome to the &lt;A href="http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=AtlasControlToolkit" target=_blank&gt;AJAX Control Toolkit&lt;/A&gt;’s NoBot control. It is an “open source” collaboration that extends the &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyId=F93BF884-EE17-4524-9E5E-EDB45F3D79F5&amp;amp;displaylang=en" target=_blank&gt;AJAX ASP.NET Extensions library&lt;/A&gt; that you can find on the &lt;A href="http://ajax.asp.net/" target=_blank&gt;Microsoft AJAX website&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The &lt;A href="http://ajax.asp.net/ajaxtoolkit/NoBot/NoBot.aspx" target=_blank&gt;NoBot&lt;/A&gt; control uses three different techniques to filter out bot postbacks on a webform:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Use a configurable JavaScript calculation to test if a browser makes the request and that the script is actually executed. 
&lt;LI&gt;The postback itself must be a certain amount of time later than the request. This is true for humans typing something into a form. 
&lt;LI&gt;A limit on the number of postbacks that can be made from a single IP address within a time window.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;I hope this will work.&lt;/P&gt;
&lt;P&gt;Also new in this release is the &lt;A href="http://blogml.com/" target=_blank&gt;BlogML 2.0&lt;/A&gt; support. BlogML is a syndication format that is gaining momentum to move your blog content to another blogging engine.&amp;nbsp;This is not just the postings, but also their categories and comments. Of course both engines must support BlogML export and import respectively. You can get the &lt;A href="http://blog.alexthissen.nl/weblog/Syndication.ashx?format=blogml20" target=_blank&gt;recent entries of my weblog as BlogML&lt;/A&gt; and even the&amp;nbsp;&lt;A href="http://blog.alexthissen.nl/weblog/Syndication.ashx?format=blogml20&amp;amp;all=true" target=_blank&gt;entire contents&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Promise to self: &lt;EM&gt;If this weblog goes down one more time due to unexplainable errors, I am switching to Community Server&lt;/EM&gt;.&amp;nbsp;The &lt;A href="'http://BLOCKEDSCRIPTWebForm_DoPostBackWithOptions(new" target=_blank&gt;Community Server 2.1 BlogML converter&lt;/A&gt; is right here, so it shouldn’t be too much of a problem. Tried and tested. (I will probably switch anyway, because CS is superior by far. I would have to give up the freedom to add whatever functionality to the blogengine I want).&lt;/P&gt;
&lt;P&gt;All of this effort is part of an important personal message I will put up shortly.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.alexthissen.nl/aggbug.aspx?PostID=2008" width="1" height="1"&gt;</description><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/AJAX/default.aspx">AJAX</category></item><item><title>Calling webservices from client-side Atlas: part 2 of 2</title><link>http://www.alexthissen.nl/blogs/main/archive/2006/07/26/calling-webservices-from-client-side-atlas-part-2-of-2.aspx</link><pubDate>Wed, 26 Jul 2006 07:29:55 GMT</pubDate><guid isPermaLink="false">badf6229-ffeb-484a-8c5a-fc9c9987c8f2:2034</guid><dc:creator>Alex Thissen</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.alexthissen.nl/blogs/main/rsscomments.aspx?PostID=2034</wfw:commentRss><comments>http://www.alexthissen.nl/blogs/main/archive/2006/07/26/calling-webservices-from-client-side-atlas-part-2-of-2.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.alexthissen.nl/weblog/DetailsView.aspx?PostingID=271f6a16-8b81-47c2-b28c-2992e68b6735"&gt;Part 1&lt;/a&gt; left us able to call web services that are local. In part 2 we will take a look at web services that are remote to our own website that hosts the Atlas enabled page. Seems like a trivial thing to do. I mean, it&amp;rsquo;s &amp;ldquo;just&amp;rdquo; a soap call over HTTP, right? The challenge lies in the fact that the MSXML2.XmlHttp COM object is not allowed to make cross-domain HTTP requests. The solution is&amp;nbsp;to bridge your call through the local website. The hosting web server will make the call on your behalf to the remote web service. The mechanism that Atlas&amp;nbsp;brings is the .asbx bridge file. A bridge file defines what the remote web service looks like.&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;xml&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;version&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;1.0&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;encoding&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;utf-8&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; ?&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;bridge&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;strong&gt;&lt;span style="COLOR:red;"&gt;namespace&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;KillerApps.Games.Atlas&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;className&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;GameServerStatus&lt;/SPAN&gt;"&lt;/strong&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;proxy&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;type&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;KillerApps.Games.Atlas.GameQueryService, App_Code&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;serviceUrl&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&amp;rdquo;http://localhost:1256/WebSite/G&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;ameQueryService.asmx&amp;rdquo;&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;method&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;&lt;STRONG&gt;GetServerStatus&lt;/STRONG&gt;&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;input&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;parameter&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;serverAddress&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;parameter&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;queryPort&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;parameter&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;engine&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;input&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;method&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;method&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;&lt;STRONG&gt;GetPlayers&lt;/STRONG&gt;&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;input&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;parameter&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;serverAddress&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;parameter&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;queryPort&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;parameter&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;engine&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;input&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;method&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;bridge&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;The XML fragment above defines a&amp;nbsp;proxy to the remote service located at the endpoint &lt;span style="COLOR:blue;"&gt;&lt;a href="http://localhost:8442/WebSite/GameQueryService.asmx"&gt;http://localhost:8442/WebSite/GameQueryService.asmx&lt;/a&gt;&lt;font color="#000000"&gt;.&amp;nbsp;Although the web service&amp;nbsp;might define more&amp;nbsp;operations two of those are mentioned and are callable by the proxy. The input and (optional) output parameters are listed as well. The proxy is a server-side class that you must provide. I used a wsdl.exe generated proxy class and included it in the App_Code folder of the Website that also hosts the .asbx file.:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR:blue;"&gt;&lt;font face="Lucida Console"&gt;wsdl.exe /language:C# /out:GameQueryServiceProxy.cs /namespace:KillerApps.Games.Atlas &lt;/font&gt;&lt;a href="http://localhost:1256/Website/Gam"&gt;&lt;font face="Lucida Console"&gt;&lt;a href="http://localhost:1256/Website/GameQueryService.asmx"&gt;http://localhost:1256/Website/Gam&lt;/font&gt;&lt;/a&gt;&lt;font face="Lucida Console"&gt;eQueryService.asmx&lt;/a&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the first part you already saw how the ScriptHandlerFactory class handles all requests for .asmx (local web services) and .asbx (bridge files to remote web services). To be able to call a remote service, simply list the location of the .asbx file instead of local .asmx file you saw before.&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;atlas&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;:&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;ScriptManager&lt;/span&gt; &lt;span style="COLOR:red;"&gt;runat&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;="server"&lt;/span&gt; &lt;span style="COLOR:red;"&gt;ID&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;="scriptManager"&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;Services&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;atlas&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;:&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;ServiceReference&lt;/span&gt; &lt;span style="COLOR:red;"&gt;Path&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;="&lt;STRONG&gt;~/GameQueryService.asbx&lt;/STRONG&gt;"&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;Services&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;atlas&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;:&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;ScriptManager&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Like before, the ScriptManager will emit JavaScript for the bridge containing an object that acts as a JavaScript proxy to the local server, which in turn bridges the call to the remote web service. The JavaScript is inserted by adding a include to the same location as the .asbx file, plus an extra /js, as in: &lt;a href="http://localhost/GameQueryService.asbx/js"&gt;http://localhost/GameQueryService.asbx/js&lt;/a&gt;. The resulting JavaScript for the bridge file above is:&lt;/p&gt;
&lt;p&gt;&lt;font face="Lucida Console"&gt;Type.registerNamespace('KillerApps.Games.Atlas'); KillerApps.Games.Atlas.GameServerStatus=new function() { this.appPath = "http://localhost:8442/WebSite/"; var cm=Sys.Net.ServiceMethod.createProxyMethod; cm(this,"GetServerStatus","args"); cm(this,"GetPlayers","args"); cm(this,"__invokeBridge","method","args"); }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;You can call the web service through the JavaScript object that has a &amp;ldquo;namespace&amp;rdquo; and &amp;ldquo;className&amp;rdquo; as indicated in the bridge file. The method names correspond to the defined methods. The call to the service looks like this:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;function&lt;/span&gt; OnLoad(sender, eventArgs)&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;{&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; KillerApps.Games.Atlas.GameServerStatus.GetServerStatus&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ( &lt;strong&gt;{ &lt;span style="COLOR:maroon;"&gt;"serverAddress"&lt;/span&gt; : &lt;span style="COLOR:maroon;"&gt;"213.132.174.125"&lt;/span&gt;, &lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR:maroon;"&gt;"queryPort"&lt;/span&gt; : 27030, &lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:maroon;"&gt;"engine"&lt;/span&gt; : &lt;span style="COLOR:maroon;"&gt;"HalfLife"&lt;/span&gt; }&lt;/strong&gt;, &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OnStatusComplete);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Notice that the bolded part is a different way to pass all parameters to the proxy. For proxies corresponding to local web services the arguments were &amp;ldquo;as always&amp;rdquo;. Now you need to define your arguments in a new Javascript dictionary. The syntax is { &amp;ldquo;parameterName1&amp;rdquo; : &amp;ldquo;argumentValue1&amp;rdquo;, &amp;ldquo;parameterName2&amp;rdquo; : &amp;ldquo;argumentValue2&amp;rdquo;, &amp;hellip; }. After the arguments you can still provide a callback methodname, plus one for timeouts and one for errors.&lt;/p&gt;
&lt;p&gt;You probably noticed that the service endpoint was a local address, that served as a remote web service for testing purposes. As soon as you want to access an actual remotely located web service, you will run into security problems. The bridge won&amp;rsquo;t let you call into cross-domain methods that are not marked safe. You do so by adding an extra attribute to each method that you consider safe (e.g. which transport non-confidential information, or the ones that cannot be misused)&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;font face="Lucida Console"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;method&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;GetServerStatus&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;safeForCrossDomain&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;true&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;This should get your web method calls to work. There is some mention of marking your web method calls as a WebOperation, like so:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;strong&gt;[&lt;span style="COLOR:teal;"&gt;WebOperation&lt;/span&gt;(&lt;span style="COLOR:blue;"&gt;true&lt;/span&gt;, &lt;span style="COLOR:teal;"&gt;ResponseFormatMode&lt;/span&gt;.Json, &lt;span style="COLOR:blue;"&gt;true&lt;/span&gt;)]&lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;[&lt;span style="COLOR:teal;"&gt;WebMethod&lt;/span&gt;]&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:teal;"&gt;ServerInfo&lt;/span&gt; GetServerStatus(&lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; serverAddress, &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; queryPort, &lt;span style="COLOR:teal;"&gt;GameEngine&lt;/span&gt; engine)&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;but I haven&amp;rsquo;t found a situation yet where this is actually necessary to do.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.alexthissen.nl/aggbug.aspx?PostID=2034" width="1" height="1"&gt;</description><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Gaming/default.aspx">Gaming</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Web+Services/default.aspx">Web Services</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/ASP.NET+2.0/default.aspx">ASP.NET 2.0</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Atlas/default.aspx">Atlas</category></item><item><title>Calling webservices from client-side Atlas: part 1 of 2</title><link>http://www.alexthissen.nl/blogs/main/archive/2006/07/20/calling-webservices-from-client-side-atlas-part-1-of-2.aspx</link><pubDate>Thu, 20 Jul 2006 21:05:14 GMT</pubDate><guid isPermaLink="false">badf6229-ffeb-484a-8c5a-fc9c9987c8f2:2039</guid><dc:creator>Alex Thissen</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.alexthissen.nl/blogs/main/rsscomments.aspx?PostID=2039</wfw:commentRss><comments>http://www.alexthissen.nl/blogs/main/archive/2006/07/20/calling-webservices-from-client-side-atlas-part-1-of-2.aspx#comments</comments><description>&lt;p&gt;The March and May 2006 CTP&amp;rsquo;s of Atlas introduced two formal ways to call web services from a web browser. The difference is in the location of the web services.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Local web services&lt;/li&gt;&lt;li&gt;Remote or external web services&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Atlas makes it really easy to call web services when they are local, i.e. reside in the same website as your Atlas-enabled web pages. You can create any ordinary .asmx web service and it will be callable from client-side JavaScript. Sure, you need to do some extra things, but there are no requirements to your service. Let&amp;rsquo;s take a look at how this works. Full source code is included at the end.&lt;/p&gt;&lt;p&gt;Say we have a web service GameQueryService.asmx&amp;nbsp;whose class is defined like so:&lt;/p&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;p style="MARGIN:0px;"&gt;[&lt;span style="COLOR:teal;"&gt;WebService&lt;/span&gt;(Namespace = &lt;span style="COLOR:maroon;"&gt;"unr:www-killerapps-nl:services:games"&lt;/span&gt;)]&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;[&lt;span style="COLOR:teal;"&gt;WebServiceBinding&lt;/span&gt;(ConformsTo = &lt;span style="COLOR:teal;"&gt;WsiProfiles&lt;/span&gt;.BasicProfile1_1)]&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;class &lt;/span&gt;&lt;span style="COLOR:teal;"&gt;GameQueryService&lt;/span&gt; : System.Web.Services.&lt;span style="COLOR:teal;"&gt;WebService&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;{&amp;nbsp;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; [&lt;span style="COLOR:teal;"&gt;WebMethod&lt;/span&gt;]&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; [&lt;span style="COLOR:teal;"&gt;XmlInclude&lt;/span&gt;(&lt;span style="COLOR:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR:teal;"&gt;HalfLifeServerInfo&lt;/span&gt;))]&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; [&lt;span style="COLOR:teal;"&gt;XmlInclude&lt;/span&gt;(&lt;span style="COLOR:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR:teal;"&gt;SourceServerInfo&lt;/span&gt;))]&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public &lt;/span&gt;&lt;span style="COLOR:teal;"&gt;ServerInfo&lt;/span&gt; GetServerStatus(&lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; serverAddress, &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; queryPort, &lt;span style="COLOR:teal;"&gt;GameEngine&lt;/span&gt; engine)&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; {&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Not relevant&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; }&amp;nbsp;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;p&gt;We want to be able to call this web service from JavaScript. In an Atlas enabled .aspx page there is always a atlas:ScriptManager control present. You need to reference the web service from there.&lt;/p&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;atlas:ScriptManager &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;runat&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;server&lt;/SPAN&gt;" &lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;ID&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;atlasScriptManager&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;Services&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;atlas:ServiceReference &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;Path&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;~/GameQueryService.asmx&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;Services&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;atlas:ScriptManager&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="COLOR:blue;"&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;div &lt;/span&gt;&lt;span style="COLOR:red;"&gt;id&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;="serverNameLabel"&amp;gt;&lt;/span&gt;Loading server information...&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;div&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;Now, the scriptmanager will do loads of things for you. First of all, it will generate JavaScript code that represents a proxy to this very web service. It makes the service available through calls as simple as this:&lt;/p&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:teal;"&gt;GameQueryService&lt;/span&gt;.GetServerStatus(&lt;span style="COLOR:maroon;"&gt;"213.132.174.125"&lt;/span&gt;, 27030, &lt;span style="COLOR:maroon;"&gt;"HalfLife"&lt;/span&gt;, OnStatusComplete);&lt;/p&gt;&lt;/div&gt;&lt;p&gt;That is almost exactly like a regular C# call to a proxy generated by wsdl.exe or Add Web Reference. The first three arguments are the ones from the WebMethod. The last one is the name of a callback JavaScript method that gets called when the call has completed.&lt;br /&gt;The magic behind the scenes is done by a different handler of .asmx requests. Web.config defines a new HttpHandler for .asmx and ties it to a ScriptHandlerFactory, allowing regular GET requests on the web service. GET requests are not supported by default in ASP.NET 2.0.&lt;/p&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;httpHandlers&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;remove &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;verb&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;*&lt;/SPAN&gt;" &lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;path&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;*.asmx&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;add &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;verb&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;*&lt;/SPAN&gt;" &lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;path&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;*.asmx&lt;/SPAN&gt;" &lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;type&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;Microsoft.Web.Services.ScriptHandlerFactory&lt;/SPAN&gt;" &lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;validate&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;false&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;add &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;verb&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;*&lt;/SPAN&gt;" &lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;path&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;*.asbx&lt;/SPAN&gt;" &lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;type&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;Microsoft.Web.Services.ScriptHandlerFactory&lt;/SPAN&gt;" &lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;validate&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;false&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;In part 2 we will get to the .asbx extension.&lt;br /&gt;You can switch off the ability to reach local web services from GET request, but this is enabled by default from the web.config&lt;/p&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;span style="COLOR:blue;"&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;microsoft.web&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;webServices &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;enableBrowserAccess&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;true&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s say we want to call this web service when the page loads. You might be tempted to use the onLoad event of the BODY tag to wait for the page to finish loading. You should &lt;u&gt;not&lt;/u&gt; do this. There is a slight delay between the&amp;nbsp;loading of the&amp;nbsp;page and the generation of the JavaScript proxy. Instead you must trigger the call to the proxy via the Atlas application object:&lt;/p&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;script &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;type&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;text/xml-script&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;page &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;xmlns:script&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;http://schemas.microsoft.com/xml-script/2005&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;components&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;application &lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;span style="COLOR:red;"&gt;load&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;"&lt;SPAN style="color:blue;"&gt;OnLoad&lt;/SPAN&gt;"&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;application&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;components&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;page&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;script&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The&amp;nbsp;OnLoad method is called when the application&amp;nbsp;has finished loading.&lt;/p&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;script&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;function&lt;/span&gt; OnLoad(sender, eventArgs)&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; {&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; GameQueryService.GetServerStatus(&lt;span style="COLOR:maroon;"&gt;"213.132.174.125"&lt;/span&gt;, 27030, &lt;span style="COLOR:maroon;"&gt;"HalfLife"&lt;/span&gt;, OnStatusComplete);&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; }&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;function&lt;/span&gt; OnStatusComplete(result)&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; {&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (result == &lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; alert(&lt;span style="COLOR:maroon;"&gt;"No response received"&lt;/span&gt;);&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt;;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; alert(result.ServerName);&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; }&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:maroon;"&gt;script&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The callback function expects a single parameter which is the result of the web service call, provided that no error or timeout has occured. In our case the result could be a null reference, so we need to test for that. But, if it is not, then you can access the result. We receive a ServerInfo (or one of its derived classes) object. The coolest thing is that you can access the&amp;nbsp;properties of the&amp;nbsp;result as if it were the actual C# object. That&amp;rsquo;s why you can access result.ServerName, because ServerName is one of the properties from the ServerInfo class.&lt;/p&gt;&lt;p&gt;You should also include a mechanism to catch timeouts and errors. For that, simply create a set of two JavaScript methods and pass the names of them as the last two arguments of the previous call to the proxy:&lt;/p&gt;&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console;"&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&lt;font color="#000000"&gt;GameQueryService.GetServerStatus(&lt;/font&gt;&lt;span style="COLOR:maroon;"&gt;"213.132.174.125"&lt;/span&gt;&lt;font color="#000000"&gt;, 27030, &lt;/font&gt;&lt;span style="COLOR:maroon;"&gt;"HalfLife"&lt;/span&gt;&lt;font color="#000000"&gt;, OnStatusComplete, OnTimeout, OnError);&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;function&lt;/span&gt; OnError(result)&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;{&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; alert(&lt;span style="COLOR:maroon;"&gt;'An error has occured. Details are listed below:\n'&lt;/span&gt; + result);&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;function&lt;/span&gt; OnTimeout(result)&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;{&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;var&lt;/span&gt; serverNameLabel = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; Sys.UI.Label($(&lt;span style="COLOR:maroon;"&gt;'serverNameLabel'&lt;/span&gt;));&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;&amp;nbsp; serverNameLabel.set_text(&lt;span style="COLOR:maroon;"&gt;'The gadget did not respond in time.'&lt;/span&gt;);&lt;/p&gt;&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The OnTimeout method has another bit of client-side Atlas, manipulating the DIV with an ID of serverNameLabel through DHTML.&lt;/p&gt;&lt;p&gt;Calling your web service&amp;rsquo;s methods turns out to be not that complicated. Things change a little when you try to access a web service that is not in the same domain. We will cover bridging such calls in the next part.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.alexthissen.nl/weblog/blogs/athissen/LocalWebservicesAtlas.zip"&gt;File Attachment: LocalWebservicesAtlas.zip (425 KB)&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.alexthissen.nl/aggbug.aspx?PostID=2039" width="1" height="1"&gt;</description><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Gaming/default.aspx">Gaming</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Web+Services/default.aspx">Web Services</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/ASP.NET+2.0/default.aspx">ASP.NET 2.0</category><category domain="http://www.alexthissen.nl/blogs/main/archive/tags/Atlas/default.aspx">Atlas</category></item></channel></rss>