<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-13566637</id><updated>2011-12-14T18:39:46.007-08:00</updated><category term='barcampcopenhagen'/><category term='barcamp'/><category term='asp.net'/><category term='performance'/><category term='weboptimizer'/><category term='outpost'/><category term='ajax'/><category term='barcampcopenhagen2008'/><title type='text'>C# Edge Blog</title><subtitle type='html'>A blog for C# and ASP.NET developers.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>34</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-13566637.post-13023520292121362</id><published>2010-05-20T03:23:00.000-07:00</published><updated>2010-05-20T03:28:18.438-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='weboptimizer'/><title type='text'>ASP.NET performance</title><content type='html'>&lt;p&gt;Check out Mads Kristensens ASP.NET performance project. 

&lt;p&gt;He tells us, that it's still in alpha, so consider it a preview. 

&lt;p&gt;&lt;a href=http://optimizeasp.net&gt;Visit OptimizeASP.NET here: http://optimizeasp.net&lt;/a&gt;

&lt;p&gt;Also, check out his open source project WebOptimizer.NET, which aim to provide friction-free performance improvements for new and existing ASP.NET applications.

&lt;p&gt;&lt;a href=http://weboptimizer.codeplex.com/&gt;Visit WebOptimzer.NET on CodePlex&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-13023520292121362?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/13023520292121362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=13023520292121362' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/13023520292121362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/13023520292121362'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2010/05/aspnet-performance.html' title='ASP.NET performance'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-9048601445779121697</id><published>2008-10-07T13:43:00.000-07:00</published><updated>2008-10-07T13:45:03.479-07:00</updated><title type='text'>BarCamp Copenhagen 8.2</title><content type='html'>&lt;P&gt;Til BarCamp Copenhagen er omdrejningspunktet de folk, der deltager, og det er her vigtigt at understrege, at der menes at deltage aktivt. No tourists!  
&lt;br&gt;

&lt;P&gt;  BarCamp konceptet er bygget op omkring discussions og open space tankegange, og det hører ind under un-conference konceptet, dvs. at programmet sættes sammen, når deltagerne dukker op. Man kan derfor heller ikke sige helt på forhånd, hvad det kommer til at handle om, men man kan kigge på deltagerlisten og google lidt på de folk, der kommer, hvis man vil danne sig et indtryk om det... En ting er sikkert, det er, at deltagerne er:
&lt;br&gt;

&lt;br&gt;
  Folk, der virkelig brænder for det, de gør.
&lt;br&gt;
  Sociale, åbne og søde mennesker.
&lt;br&gt;
  Mennesker, der elsker at dele ud af deres viden.
&lt;br&gt;
  Interesserede, intelligente og intense personer.
&lt;br&gt;
  - og der kan være tendens til høj GEEK-faktor.
&lt;br&gt;

&lt;P&gt;  Der er deltagerloft på 50, så man skal være lidt hurtig til at tilmelde sig på wikien, http://barcamp.org/BarCampCopenhagen.
&lt;P&gt;  Vi har ikke en location fastlagt endnu, og vi mangler sponsorer, men datoen er under alle omstændigheder den 22. november, fra kl. 10-?
&lt;br&gt;
&lt;P&gt;  Det gælder om at deltage, både før, under og efter, så blog om det og sig det videre.
&lt;br&gt;

&lt;P&gt;  - Velkommen til den danske it-undergrund!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-9048601445779121697?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/9048601445779121697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=9048601445779121697' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/9048601445779121697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/9048601445779121697'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2008/10/barcamp-copenhagen-82.html' title='BarCamp Copenhagen 8.2'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-7164951836520669597</id><published>2008-04-06T08:06:00.000-07:00</published><updated>2008-04-06T08:12:38.707-07:00</updated><title type='text'>OutPost 3.2.001</title><content type='html'>&lt;p&gt;The long awaited release!&lt;/p&gt;

&lt;ul&gt;
&lt;li class="download"&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost.3.2.001.zip"&gt;&lt;u&gt;Download OutPost 3.2.001&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changes since last release, which was 2.2.002:&lt;/p&gt;

&lt;ul class="history"&gt;
    &lt;li&gt;6/4-2008 - 3.2.001
      &lt;ul&gt;
        &lt;li&gt;First PUBLIC release since version 2.0.003!&lt;/li&gt;
        &lt;li&gt;Added support for asynchronous page flakes that loads simultaneously.&lt;/li&gt;
        &lt;li&gt;Added better support for external page flakes.&lt;/li&gt;
        &lt;li&gt;Improved support for Internet Explorer, Firefox, Opera and Safari browsers.&lt;/li&gt;
        &lt;li&gt;Removes linebreaks when comparing for differences to minimize traffic.&lt;/li&gt;
        &lt;li&gt;No more supports .net 1.1 (officially).&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;1/2-2008 - 3.1.001
      &lt;ul&gt;
        &lt;li&gt;Added Suggest.aspx demo.&lt;/li&gt;
        &lt;li&gt;Added DocTree.aspx demo.&lt;/li&gt;
        &lt;li&gt;Redesigned test suite layout.&lt;/li&gt;
        &lt;li&gt;Added support for animations, like YellowFade, BackFade, SlideDown and more.&lt;/li&gt;
        &lt;li&gt;Added support for loading indicator.&lt;/li&gt;
        &lt;li&gt;Added support for load indicator.&lt;/li&gt;
        &lt;li&gt;Added method to Disable Ajax.&lt;/li&gt;
        &lt;li&gt;Added support for asynchronous load of Page control after window.onload.&lt;/li&gt;
        &lt;li&gt;Redesigned the iGoogle demo to make it more modular and extendable.&lt;/li&gt;
        &lt;li&gt;Improved the SignUp demo.&lt;/li&gt;
        &lt;li&gt;Added AjaxPage user control.&lt;/li&gt;
        &lt;li&gt;Added DataGrid Demo.&lt;/li&gt;
        &lt;li&gt;Added ProperReset Demo.&lt;/li&gt;
        &lt;li&gt;Added ToDoList Flake for iGoogle demo.&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;27/11-2007 - 3.0.002
      &lt;ul&gt;
        &lt;li&gt;Modified web.config to make it work with ASP.NET Development Server.&lt;/li&gt;
        &lt;li&gt;Edited the howto.txt.&lt;/li&gt;&lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;21/04-2007 - 3.0.001
      &lt;ul&gt;
        &lt;li&gt;Added option to hijack links.&lt;/li&gt;
        &lt;li&gt;Added support to ajax-enable a page from web.config.&lt;/li&gt;
        &lt;li&gt;Redesigned and reimplemented the html compare function by using LCS algorithm.&lt;/li&gt;
        &lt;li&gt;Optimized splitting up the HTML into tags by using split in combination with regular expressions.&lt;/li&gt;
        &lt;li&gt;Optimized every use of regular expressions by caching the results.&lt;/li&gt;
        &lt;li&gt;Huge performance improvements!!&lt;/li&gt;
        &lt;li&gt;Added option EnableAjaxRedirect which allows the page to be redirected using ajax.&lt;/li&gt;
        &lt;li&gt;Added support for multiple-select drop down lists.&lt;/li&gt;
        &lt;li&gt;Improved support for tables.&lt;/li&gt;
        &lt;li&gt;Improved support for loading of scripts.&lt;/li&gt;
        &lt;li&gt;Added update commands InsertAfter and InsertFirst.&lt;/li&gt;
        &lt;li&gt;Improved cursor position store/restore functionality.&lt;/li&gt;
        &lt;li&gt;Added scroll position store/restore functionality.&lt;/li&gt;
        &lt;li&gt;Added support for external hosts by introducing keyword $ExternalHost$ for the LocalHost property.&lt;/li&gt;
        &lt;li&gt;Reimplemented the Page control as a UserControl.&lt;/li&gt;
        &lt;li&gt;Added ExternalTest.aspx demo.&lt;/li&gt;
        &lt;li&gt;Added FormElementsTest.aspx demo.&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;15/03-2007 - 2.0.003
      &lt;ul&gt;
        &lt;li&gt;Added support for not sending back inputs with only the value changed.&lt;/li&gt;
        &lt;li&gt;Fixed bug with resetting radio buttons.&lt;/li&gt;
        &lt;li&gt;Reduced number of unnecessary field updates on the client.&lt;/li&gt;
        &lt;li&gt;Added support for ASP.NET 1.1.&lt;/li&gt;
        &lt;li&gt;Added support for following parameters: DisableCopyCommand, ShowViewState, ShowEventValidation,
          ShowLastFocus, SimulateOnload, SimulateOnunload, SimulateOnbeforeunload&lt;/li&gt;
        &lt;li&gt;Added ProperReset demo.&lt;/li&gt;&lt;/ul&gt;
    &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://hijax.net/OutPost/3.2.001/Core/History.html"&gt;Find the full history here&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-7164951836520669597?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/7164951836520669597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=7164951836520669597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/7164951836520669597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/7164951836520669597'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2008/04/outpost-32001.html' title='OutPost 3.2.001'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-5002468018961793337</id><published>2008-03-22T15:36:00.000-07:00</published><updated>2008-03-23T14:00:43.192-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='barcampcopenhagen2008'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='barcamp'/><category scheme='http://www.blogger.com/atom/ns#' term='barcampcopenhagen'/><title type='text'>Slides from barCamp Copenhagen 2008</title><content type='html'>&lt;p&gt;Here are the slides and the transcript of my presentation at barCamp Copenhagen 2008. The presentation was held in Danish, so I've translated the slides and the transcript into English.&lt;/p&gt;

&lt;h2&gt;Transcript&lt;/h2&gt;

&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_1.png'/&gt;
   &lt;/p&gt;&lt;p&gt;Hi, my name is Troels, I work for a company called beaconware. 
&lt;/p&gt;&lt;p&gt;I primarily work with .net technology and web development.
&lt;/p&gt;&lt;p&gt;I would like to tell you about ajax and about how you go from ajax to hijax to indirect ajax.
&lt;/p&gt;&lt;p&gt;I'll round this session of with a demo about how indirect ajax works.
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_2.png'/&gt;
   &lt;/p&gt;&lt;p&gt;There are a lot of definitions of what ajax is. A simple definition would be: 
&lt;/p&gt;&lt;p&gt;"Ajax is the ability to update a part of the page instead of the whole page." 
&lt;/p&gt;&lt;p&gt;It may not sound overwhelming.
&lt;/p&gt;&lt;p&gt;The strength lies in the ability to call the server asynchronously without reloading the page. 
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_3.png'/&gt;
   &lt;/p&gt;&lt;p&gt;An example could be an explorer in a CMS with folders that you can expand to reveal documents and sub folders. 
&lt;/p&gt;&lt;p&gt;You could achieve this with ajax by attaching a handler on the click event. 
&lt;/p&gt;&lt;p&gt;The handler would call a web service asynchronously to get a data representation of the contents of the folder. 
&lt;/p&gt;&lt;p&gt;Then it would add graphics needed for documents and sub folders to the document structure below the expanded folder. 
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_4.png'/&gt;
   &lt;/p&gt;&lt;p&gt;The great challenge in programming ajax is to make it work in all browsers.
&lt;/p&gt;&lt;p&gt;It's difficult and the end user must often download huge scripts to make it work. 
&lt;/p&gt;&lt;p&gt;Browsers in cell phones has extra difficulties with ajax because they don't have full dynamic html support. 
&lt;/p&gt;&lt;p&gt;If you make your web application depend on ajax, then you have to realize that there will be end users 
&lt;/p&gt;&lt;p&gt;who are unable to use it, either because of their browsers or because of other accesibility concerns. 
&lt;/p&gt;&lt;p&gt;That's why it's so important to make sure that the ajax application degrades gracefully, which means that beneath
&lt;/p&gt;&lt;p&gt;all the fancy web 2.0 fireworks there's a fully functional web 1.0 document to fall-back on. 
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_5.png'/&gt;
   &lt;/p&gt;&lt;p&gt;This is where hijax gets into play. 
&lt;/p&gt;&lt;p&gt;Hijax is a method that reminds you of how you achieve separation of layout from document structure by using css files.
&lt;/p&gt;&lt;p&gt;With hijax you achieve separation of ajax from the document structure. 
&lt;/p&gt;&lt;p&gt;The procedure is to start by developing a fully functional web 1.0 document by using forms and links. 
&lt;/p&gt;&lt;p&gt;Then you hijack the form's "onsubmit" event and the link's "onclick" event by using unobtrusive Javascript.
&lt;/p&gt;&lt;p&gt;That means Javascript that automatically disables itself in a down-level browser.
&lt;/p&gt;&lt;p&gt;So, if the browser doesn't live up to the requirements for ajax then the application reverts to web 1.0 behaviour.
&lt;/p&gt;&lt;p&gt;When a form's onsubmit event has been hijacked and it gets intercepted then an asynchronous call is made to a web service on the server. 
&lt;/p&gt;&lt;p&gt;The server returns the requested html fragment and the client updates the DOM. 
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_6.png'/&gt;
   &lt;/p&gt;&lt;p&gt;The technique used here is also called AHAH which stands for Asynchronous Html And Http. You can find it on microformats.org. 
&lt;/p&gt;&lt;p&gt;Hijax requires that you in your server code is able to separate the output into those html fragments that you want to update separately on the client. 
&lt;/p&gt;&lt;p&gt;So you need a really flexible server API that can return parts of the page by request. 
&lt;/p&gt;&lt;p&gt;It can seem as a comprehensive task to make your web application ready for this and it is, especially if you don't do it from the beginning. 
&lt;/p&gt;&lt;p&gt;You will have to create web services that you can call and a way of telling them which part of which page that you want html returned for.
&lt;/p&gt;&lt;p&gt;Not to mention thinking up a way of handling actions and events on the server. 
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_7.png'/&gt;
   &lt;/p&gt;&lt;p&gt;That is why some people gone a step further and invented indirect ajax. 
&lt;/p&gt;&lt;p&gt;Indirect ajax automates the process of hijaxing a form. 
&lt;/p&gt;&lt;p&gt;It hijacks all events and communicates with the server through a proxy. 
&lt;/p&gt;&lt;p&gt;The proxy receives enough information to execute the http request that would have been executed if the event hadn't been intercepted. 
&lt;/p&gt;&lt;p&gt;The only difference is that the call is executed locally on the server and a lot faster. 
&lt;/p&gt;&lt;p&gt;The html document that is returned by this call is stored in memory on the server to be compared with the html document returned by the next call.
&lt;/p&gt;&lt;p&gt;So, on every request the current document is compared to the previous document. 
&lt;/p&gt;&lt;p&gt;The comparison results in a difference. This difference consists of a number of html fragments together with information about where they belong in the document structure. 
&lt;/p&gt;&lt;p&gt;This information is sent back to the client that now updates the document structure. 
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_8.png'/&gt;
   &lt;/p&gt;&lt;p&gt;On the screen it looks like the browser executes a normal post back. It's just quicker, because:
&lt;/p&gt;&lt;p&gt;-  The traffic to and from the server has been minimized.
&lt;/p&gt;&lt;p&gt; - and because the call is executed locally on the server
&lt;/p&gt;&lt;p&gt;- and because it doesn't require the whole page to be reloaded.
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_9.png'/&gt;
   &lt;/p&gt;&lt;p&gt;Now I want to show you a couple of demoes of an indirect ajax framework.
&lt;/p&gt;&lt;p&gt;It's an open source project that I have developed for .net and it's called OutPost.
&lt;/p&gt;&lt;p&gt;You can try out or download the demo from http://hijax.net/OutPost.
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_10.png'/&gt;
   &lt;/p&gt;&lt;p&gt;The first demo is inspired by Google Suggest which is a really classic ajax tool.
&lt;/p&gt;&lt;p&gt;As you type in words in the search field the suggestions for search terms are shown below based on searches of other users.
&lt;/p&gt;&lt;p&gt;I twisted it and made a Farber Suggest application based on the hilarious turns of phrases of David Farber.
&lt;/p&gt;&lt;p&gt;Here you type in an English word and then a number of matching farberisms are shown below.
&lt;/p&gt;&lt;p&gt;Let's try... 
&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;img width="100%" alt='' src='http://hijax.net/barcampcopenhagen2008/032208_2304_11.png'/&gt;
   &lt;/p&gt;&lt;p&gt;The other demo is a simple explorer that shows folders and documents in a CMS. 
&lt;/p&gt;&lt;p&gt;You can click on a folder to expand it. 
&lt;/p&gt;&lt;p&gt;You can also collapse the folder again by clicking on it. 
&lt;/p&gt;&lt;p&gt;In the background I have a program called Fiddler running. It logs the traffic between client and server.
&lt;/p&gt;&lt;p&gt;As you can see the server sends about 8kb back on every request.
&lt;/p&gt;&lt;p&gt;Now  I enable OutPost.
&lt;/p&gt;&lt;p&gt;And run the demo again.
&lt;/p&gt;&lt;p&gt;Looking at the source code you can see that some details in the html code has changed to make OutPost able to hijack the events that normally gets the browser to reload the page. 
&lt;/p&gt;&lt;p&gt;Then we expand the folder... And expand the sub folder...
&lt;/p&gt;&lt;p&gt;And then we switch to Fiddler again. 
&lt;/p&gt;&lt;p&gt;As you can see the amount of traffic is now about 10 times smaller. 
&lt;/p&gt;&lt;p&gt;This is partly a result of zipping the traffic. So, we use Fiddler to unzip it. 
&lt;/p&gt;&lt;p&gt;And if we dive deeper in to see the data itself we can see that it's not a full document that's returned to the client. 
&lt;/p&gt;&lt;p&gt;The client receives commands that the OutPost client framework understands and uses to update the document structure with. 
&lt;/p&gt;&lt;p&gt;As an example one command means "replace this image with this" and another means "delete this table". 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-5002468018961793337?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/5002468018961793337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=5002468018961793337' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/5002468018961793337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/5002468018961793337'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2008/03/slides-from-barcamp-copenhagen-2008.html' title='Slides from barCamp Copenhagen 2008'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-4406057040124786274</id><published>2008-01-25T12:16:00.000-08:00</published><updated>2008-01-25T12:24:57.494-08:00</updated><title type='text'>BarCamp Copenhagen 2008</title><content type='html'>&lt;p&gt;Cool event, nice people, great atmosphere!!
&lt;p&gt;Here is a link to the demoes, I've just put them online, including at download link to the latest unofficial BETA of OutPost: &lt;a href="http://hijax.net/OutPost"&gt;http://hijax.net/OutPost&lt;/a&gt;
&lt;p&gt;My presentation was well received. You can download the power points here (sorry it's only in power point 2007 format right now - AND it's in Danish): &lt;a href="http://hijax.net/OutPost/AJAX, HIJAX, OUTPOST.pptx"&gt;AJAX, HIJAX, OUTPOST&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-4406057040124786274?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/4406057040124786274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=4406057040124786274' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/4406057040124786274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/4406057040124786274'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2008/01/barcamp-copenhagen-2008.html' title='BarCamp Copenhagen 2008'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-5417402084659600959</id><published>2007-11-27T06:21:00.000-08:00</published><updated>2007-11-27T06:27:25.711-08:00</updated><title type='text'>OutPost and ASP.NET Development Server</title><content type='html'>&lt;p&gt;I just found out, that OutPost has some troubles with the way ASP.NET Development Server handles &lt;strong&gt;httphandlers&lt;/strong&gt;. The &lt;httphandlers&gt;section of web.config can be modified to make it work:

&lt;p&gt;&lt;b&gt;Change this:&lt;/b&gt;

&lt;/p&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;&lt;&lt;/span&gt;&lt;span style="font-size:85%;color:#a31515;"&gt;add&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:#ff0000;"&gt;verb&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;=&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;*&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:#ff0000;"&gt;path&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;=&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;OutPost.axd&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:#ff0000;"&gt;type&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;=&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;OutPost.Core.Switch,OutPost&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;/&gt;&lt;/span&gt;

&lt;p&gt;&lt;b&gt;to this:&lt;/b&gt;

&lt;/p&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;&lt;&lt;/span&gt;&lt;span style="font-size:85%;color:#a31515;"&gt;add&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:#ff0000;"&gt;verb&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;=&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;*&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:#ff0000;"&gt;path&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;=&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;OutPost.axd,OutPost.axd/Ajax.js&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:#ff0000;"&gt;type&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;=&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;OutPost.Core.Switch,OutPost&lt;/span&gt;&lt;span style="font-size:85%;"&gt;"&lt;/span&gt;&lt;span style="font-size:85%;color:#0000ff;"&gt;/&gt;&lt;/span&gt;

&lt;p&gt;And it now works with ASP.NET Development Server&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-5417402084659600959?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/5417402084659600959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=5417402084659600959' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/5417402084659600959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/5417402084659600959'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2007/11/outpost-and-aspnet-development-server.html' title='OutPost and ASP.NET Development Server'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-8397168714749789971</id><published>2007-11-27T05:03:00.000-08:00</published><updated>2007-11-27T05:08:53.154-08:00</updated><title type='text'>OutPost Demo HowTo for .NET 2.0</title><content type='html'>&lt;p&gt;&lt;b&gt;For ASP.NET 2.0 demo&lt;/b&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download and unzip OutPost.zip
&lt;li&gt;Open folder "Demo"
&lt;li&gt;Right-click sub folder "Outpost-2.0-Demo"
&lt;li&gt;Select "Properties"
&lt;li&gt;Select "Web Sharing"
&lt;li&gt;Select "Share this folder", alias should be "Outpost-2.0-Demo"
&lt;li&gt;If .NET 2.0 isn't your default setting you must configure this with Internet Information Services
&lt;li&gt;Now you can open the demo at "http://localhost/Outpost-2.0-Demo/Demo"
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-8397168714749789971?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/8397168714749789971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=8397168714749789971' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/8397168714749789971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/8397168714749789971'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2007/11/outpost-demo-howto-for-aspnet-20.html' title='OutPost Demo HowTo for .NET 2.0'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-437169230640210845</id><published>2007-11-05T14:18:00.000-08:00</published><updated>2007-11-05T14:24:35.804-08:00</updated><title type='text'>BarCampCopenhagen</title><content type='html'>I'm making a presentation at BarCampCopenhagen about OutPost.

It's in Copenhagen on January 25th, 2008. Hope to see you there!

The next release is on its way and includes a lot of improvements.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-437169230640210845?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/437169230640210845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=437169230640210845' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/437169230640210845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/437169230640210845'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2007/11/barcampcopenhagen.html' title='BarCampCopenhagen'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-3035858822836712004</id><published>2007-03-15T15:58:00.000-07:00</published><updated>2007-11-27T06:46:06.442-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='outpost'/><title type='text'>OutPost Marketing blah</title><content type='html'>&lt;p&gt;OutPost hijacks the form post back event and
&lt;ul class="list"&gt;&lt;li&gt;tells the server to execute the post back locally on the server,
&lt;/li&gt;&lt;li&gt;an optimized DHTML-response is sent back to the client,
&lt;/li&gt;&lt;li&gt;the page is updated using cross-browser DHTML and
&lt;/li&gt;&lt;li&gt;page reloads and flickers are thereby eliminated.
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Bandwidth usage is minimized by
&lt;ul class="list"&gt;&lt;li&gt;diff-comparing two consecutive responses,
&lt;/li&gt;&lt;li&gt;keeping state on server,
&lt;/li&gt;&lt;li&gt;keeping js framework light,
&lt;/li&gt;&lt;li&gt;compressing the response,
&lt;/li&gt;&lt;li&gt;sending optimized DHTML and
&lt;/li&gt;&lt;li&gt;not using Xml or JSON.
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Features
&lt;ul class="list"&gt;&lt;li&gt;No custom controls needed
&lt;/li&gt;&lt;li&gt;No update panels required
&lt;/li&gt;&lt;li&gt;No Javascript/DOM skills required
&lt;/li&gt;&lt;li&gt;Write ASP.NET like you use to do
&lt;/li&gt;&lt;li&gt;Design your page like you use to do
&lt;/li&gt;&lt;li&gt;Internal HTTP-compression
&lt;/li&gt;&lt;li&gt;Multiple flakes on same page
&lt;/li&gt;&lt;li&gt;One line of code enables Ajax
&lt;/li&gt;&lt;li&gt;Pages can be included in other pages
&lt;/li&gt;&lt;li&gt;Add form using client-scripting
&lt;/li&gt;&lt;li&gt;Cross-form posting
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Supports
&lt;ul class="list"&gt;&lt;li&gt;ASP.NET 1.1 &amp;amp; 2.0 controls
&lt;/li&gt;&lt;li&gt;Session state
&lt;/li&gt;&lt;li&gt;ViewState
&lt;/li&gt;&lt;li&gt;Caching
&lt;/li&gt;&lt;li&gt;Url redirects
&lt;/li&gt;&lt;li&gt;Server events
&lt;/li&gt;&lt;li&gt;Most browsers
&lt;/li&gt;&lt;li&gt;Form authentication
&lt;/li&gt;&lt;li&gt;HTTPS
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Options
&lt;ul class="list"&gt;&lt;li&gt;Simulate onload event on postbacks
&lt;/li&gt;&lt;li&gt;Simulate onunload event on postbacks
&lt;/li&gt;&lt;li&gt;Simulate onbeforeunload event on postbacks
&lt;/li&gt;&lt;li&gt;Keep/reset client-side events on postbacks
&lt;/li&gt;&lt;li&gt;Show/hide ViewState
&lt;/li&gt;&lt;li&gt;Show/hide EventValidation
&lt;/li&gt;&lt;li&gt;Turn compression on/off
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-3035858822836712004?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/3035858822836712004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=3035858822836712004' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/3035858822836712004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/3035858822836712004'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2007/03/outpost-sales-pitch.html' title='OutPost Marketing blah'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-8417185910449784554</id><published>2007-03-15T02:45:00.000-07:00</published><updated>2007-03-15T02:47:19.320-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='outpost'/><title type='text'>OutPost 2.0.002</title><content type='html'>&lt;p&gt;New demo added and some bugfixes.&lt;/p&gt;

&lt;ul&gt;
&lt;li class="download"&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost.2.0.002.zip"&gt;&lt;u&gt;Download OutPost 2.0.002&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changes since last release, which was 2.0.001:&lt;/p&gt;

&lt;ul class="history"&gt;
  &lt;li&gt;15/03-2007 - 2.0.002
    &lt;ul&gt;
      &lt;li&gt;Fixed bugs in iGoogle demo.&lt;/li&gt;
      &lt;li&gt;Fixed properly resetting Page_Validators array on post backs.&lt;/li&gt;
      &lt;li&gt;Added Wizard demo.&lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-8417185910449784554?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/8417185910449784554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=8417185910449784554' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/8417185910449784554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/8417185910449784554'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2007/03/outpost-20002.html' title='OutPost 2.0.002'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-7469229653757746901</id><published>2007-03-13T16:49:00.000-07:00</published><updated>2007-03-13T17:04:08.319-07:00</updated><title type='text'>OutPost 2.0 Released</title><content type='html'>&lt;p&gt;New version ready to download!&lt;/p&gt;

&lt;p&gt;It is much better at dividing the page up and sending only what's changed. One of the reasons for this is that OutPost no longer restricts itself to looking at html tags that has an ID on them. Any element goes! Also a Delete command and a Copy command is introduced.&lt;/p&gt;

&lt;p&gt;Hope you like it and have fun with it! Please, write a comment if you use it for something cool!&lt;/p&gt;

&lt;ul&gt;
&lt;li class="download"&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost.2.0.001.zip"&gt;&lt;u&gt;Download OutPost 2.0.001&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changes since last release, which was 1.6.002:&lt;/p&gt;

&lt;ul class="history"&gt;
  &lt;LI&gt;
    14/03-2007 - 2.0.001&lt;/LI&gt;
  &lt;UL&gt;
    &lt;li&gt;
      Added support for specifying LocalHost dynamically by setting it to $CURRENTHOST$.&lt;/li&gt;
    &lt;LI&gt;
      Added support for hiding LASTFOCUS field.&lt;/LI&gt;
    &lt;LI&gt;
      Fixed support for storing/restoring selected text.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for client debugging modes.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for simulating (triggering) onload, onunload and onbeforeunload events.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for client side debugging for Ajax javascript.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for adding rows to tables.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for url redirect&lt;/LI&gt;
    &lt;LI&gt;
      Added support for deleting elements by sending a Delete command to the client.&lt;/LI&gt;
    &lt;LI&gt;
      Added WebParts and Cars demoes.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for chunked response.&lt;/LI&gt;&lt;/UL&gt;
  &lt;LI&gt;
    23/01-2007 - 1.7.001&lt;/LI&gt;
  &lt;UL&gt;
    &lt;li&gt;
      Added support for adding client side event 'onsuccess' to the form.&lt;/li&gt;
    &lt;LI&gt;
      Added support for sending modified tags without id or name back to the client.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for copying html from elements that are already present on the client to other elements in stead of sending it again.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for sending table rows (tr) back to client.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for sending only value of input tags back.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for sending only modified script blocks back to the client.&lt;/LI&gt;
    &lt;LI&gt;
      Added cross-browser support for using following DHTML features: outerHTML, replaceNode, parentElement, canHaveChildren.&lt;/LI&gt;
    &lt;LI&gt;
      Added support for adding response headers by specifying appsetting "AddHeaders" (syntax "key1=value1&amp;key2=value2").&lt;/LI&gt;
    &lt;LI&gt;
      Fixed problem with repeatedly submitting a form and not getting the form updated or reset (as pointed out by Jomar Coquia).&lt;/LI&gt;&lt;/UL&gt;
  &lt;LI&gt;
    23/11-2006 - 1.6.004&lt;/LI&gt;
  &lt;UL&gt;
    &lt;LI&gt;
      Fixed problem with inserting carriage returns into textarea.&lt;/LI&gt;&lt;/UL&gt;
  &lt;LI&gt;
    15/11-2006 - 1.6.003&lt;/LI&gt;
  &lt;UL&gt;
    &lt;LI&gt;
      Added if there is no difference between two or more post backs the browser is
      re-updated with the last post back that had a difference. That means if you
      modify the DOM between the post backs this resets some or all of these modifications 
      (which i closer than before to what is normally expected).&lt;/LI&gt;&lt;/UL&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-7469229653757746901?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/7469229653757746901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=7469229653757746901' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/7469229653757746901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/7469229653757746901'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2007/03/outpost-20-released.html' title='OutPost 2.0 Released'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-116056339567500614</id><published>2006-10-11T03:40:00.000-07:00</published><updated>2006-10-11T03:58:20.086-07:00</updated><title type='text'>OutPost 1.6</title><content type='html'>&lt;ul&gt;
&lt;li class=download&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost.1.6.002.zip"&gt;&lt;u&gt;Download OutPost 1.6.002&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;UL class=history&gt;
  &lt;LI&gt;
    11/10-2006 - 1.6.002&lt;/LI&gt;
  &lt;UL&gt;
    &lt;LI&gt;
    Added new Demo in .NET 1.1 project /Brian Ritchie
    &lt;LI&gt;
      Fixed a bug where&amp;nbsp;a drop down populates, but resets the position on post 
      back&lt;/LI&gt;&lt;/UL&gt;
  &lt;LI&gt;
    10/10-2006 - 1.6.001
    &lt;UL&gt;
      &lt;LI&gt;
      Placed version history in separate file
      &lt;LI&gt;
      Utilized HttpHandler instead of Page with code behind. This requires a simple 
      entry in the web.config /Brian Ritchie
      &lt;LI&gt;
      Removed 3rd party code and include binary libraries instead (sharpziplib &amp;amp; 
      blowery) /Brian Ritchie
      &lt;LI&gt;
      Packaged things up into a class library /Brian Ritchie
      &lt;LI&gt;
        Enhanced 1.1 support so it compiles under 1.1 again /Brian Ritchie&lt;/LI&gt;&lt;/UL&gt;
&lt;/UL&gt;

&lt;p&gt;See full &lt;a href="http://hijax.net/OutPost/OutPost/History.html"&gt;Version history&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-116056339567500614?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/116056339567500614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=116056339567500614' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/116056339567500614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/116056339567500614'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/10/outpost-16.html' title='OutPost 1.6'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-116013800495243082</id><published>2006-10-06T05:29:00.000-07:00</published><updated>2006-10-06T05:35:29.486-07:00</updated><title type='text'>Benefits of Hijax</title><content type='html'>&lt;p&gt;Did a search on Hijax and found a link to the slides from &lt;a href="http://domscripting.com/presentations/xtech2006/"&gt;Jeremy Keith's presentation at XTech 2006&lt;/a&gt;. Here's a nice quote from the presentation slides:
&lt;/p&gt;

&lt;blockquote&gt;&lt;h2&gt;Benefits of Hijax&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;No need to spend time and resources building a non-Ajax version.&lt;/li&gt;
&lt;li&gt;No duplication of logic (e.g. form validation).&lt;/li&gt;
&lt;li&gt;Keeps your application logic on the server.&lt;/li&gt;
&lt;li&gt;Keeps your JavaScript file size down.&lt;/li&gt;
&lt;li&gt;Links are spiderable and potentially bookmarkable.&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-116013800495243082?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/116013800495243082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=116013800495243082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/116013800495243082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/116013800495243082'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/10/benefits-of-hijax.html' title='Benefits of Hijax'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-115996149082330867</id><published>2006-10-04T04:29:00.000-07:00</published><updated>2006-10-04T04:31:30.836-07:00</updated><title type='text'>OutPost 1.5 Refresh</title><content type='html'>&lt;ul&gt;
&lt;li class=download&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost15.zip"&gt;&lt;u&gt;Download OutPost 1.5&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;10/4-2006 - 1.5.003&lt;/p&gt;
&lt;ul class=donors&gt;&lt;li&gt;Removed bits of Javascript that wasn't used for anything
&lt;li&gt;Added more thorough removal of EventValidation and ViewState input including surrounding DIVs
&lt;/ul&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-115996149082330867?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/115996149082330867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=115996149082330867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115996149082330867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115996149082330867'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/10/outpost-15-refresh.html' title='OutPost 1.5 Refresh'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-115966669416504792</id><published>2006-09-30T18:34:00.000-07:00</published><updated>2006-09-30T18:48:36.623-07:00</updated><title type='text'>OutPost version 1.5</title><content type='html'>&lt;b&gt;Added gzip and deflate compression internally! Now it really rocks :)&lt;/b&gt;

&lt;ul&gt;
&lt;li class=download&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost15.zip"&gt;&lt;u&gt;OutPost 1.5&lt;/u&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1.5.002 - 20061001 0312 twj
&lt;ul class=donors&gt;&lt;li&gt;Removed selected="selected" when comparing html, it caused dropdown boxes to be refreshed without more often than needed
&lt;li&gt;Removed call to oForm_doReset after each post back because of the change to the dropdowns
&lt;li&gt;Added update of SignUp demo - it now has 3 "linked" controls (two drop-downs and a text field)
&lt;/ul&gt;
&lt;p&gt;1.5.001 - 20061001 0014 twj
&lt;ul class=donors&gt;&lt;li&gt;Added gzip and deflate compression internally
&lt;li&gt;Changed namespace OutPost.Core to OutPost
&lt;li&gt;Removed constant ContentTypeForNoCompression
&lt;/ul&gt;
&lt;p&gt;1.4.004 - 20060928 1107 twj
&lt;ul class=donors&gt;&lt;li&gt;Added error message when trying to view OutPost.aspx directly
&lt;li&gt;Added MinimumSizeForCompression and ContentTypeForNoCompression constants
&lt;/ul&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;If you occasionally look at my blog, please drop me a comment once in a while. It keeps me going :) and hopefully keeps me delivering the best performing indirect ajax framework in the world!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-115966669416504792?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/115966669416504792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=115966669416504792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115966669416504792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115966669416504792'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/09/outpost-version-15.html' title='OutPost version 1.5'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-115943563533294909</id><published>2006-09-28T02:25:00.000-07:00</published><updated>2006-09-28T02:36:17.090-07:00</updated><title type='text'>OutPost 1.4 Refresh</title><content type='html'>&lt;p&gt;I have made som optimizations to version 1.4. Download and update for better performance.&lt;/p&gt;

&lt;p&gt;1.4.003 - 20060928 1107 twj&lt;/p&gt;
&lt;ul class=donors&gt;&lt;li&gt;Changed "SessionID" and "session" to "GUID" and "guid"
&lt;li&gt;Optimized client framework size by removing spaces and replacing variable names
&lt;/ul&gt;

&lt;p&gt;1.4.002 - 20060927 1444 twj&lt;/p&gt;
&lt;ul class=donors&gt;&lt;li&gt;Added default setting of PartsNeeded for GET request
&lt;li&gt;Changed "SessionID" and "session" to "GUID" and "guid"
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-115943563533294909?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/115943563533294909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=115943563533294909' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115943563533294909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115943563533294909'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/09/outpost-14-refresh.html' title='OutPost 1.4 Refresh'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-115931367567076916</id><published>2006-09-26T16:29:00.000-07:00</published><updated>2006-09-26T16:40:00.203-07:00</updated><title type='text'>OutPost version 1.4</title><content type='html'>&lt;ul class=download&gt;
&lt;li&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost14.zip"&gt;Download OutPost 1.4 (with source code)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This release focuses on optimization of traffic between client and server. As a result of moving away from using SOAP I reduced traffic overhead dramatically.&lt;/p&gt;

&lt;p&gt;I also made a &lt;a href=http://hijax.net/Demo&gt;OutPost 1.4 demo site - try it out!&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-115931367567076916?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/115931367567076916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=115931367567076916' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115931367567076916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115931367567076916'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/09/outpost-version-14.html' title='OutPost version 1.4'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-115888245950522426</id><published>2006-09-21T16:38:00.000-07:00</published><updated>2006-09-21T16:47:39.516-07:00</updated><title type='text'>OutPost version 1.3</title><content type='html'>&lt;P&gt;Version 1.3 now available.&lt;/P&gt;
&lt;ul class=download&gt;
&lt;li&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost13.zip"&gt;OutPost 1.3 (with source code)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A lot of improvements has gone into this release:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;New demo with a Sign-Up web form (by request).
&lt;li&gt;Removed Session dependency.
&lt;li&gt;Restores position and selection in IE on postback.
&lt;li&gt;Found problems with unicode characters. As it is your page must include the tag
ResponseEncoding="utf-8" in order to work properly with Unicode characters.
&lt;li&gt;Added a cloak (event trap) over the form in IE on postback in order to mimick default web form behaviour.
&lt;li&gt;Added support for WebForm_AutoFocus.
&lt;li&gt;Added support for queueing requests.
&lt;li&gt;Added support for reloading script blocks.
&lt;li&gt;Added setting LocalHost to specify alternative localhost domain.
&lt;li&gt;Added support for HTTP-compression (tested with FlatCompression R1.20.226 from www.flatcompression.org).
&lt;li&gt;A lot of bugs fixed.
&lt;/ul&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-115888245950522426?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/115888245950522426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=115888245950522426' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115888245950522426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/115888245950522426'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/09/outpost-version-13.html' title='OutPost version 1.3'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-114501770200326202</id><published>2006-04-14T05:27:00.000-07:00</published><updated>2006-04-18T04:36:51.126-07:00</updated><title type='text'>BusinessLogic.web - a .NET business logic wrapper for Javascript</title><content type='html'>&lt;p&gt;This is a sample of BusinessLogic.web - A javascript business logic wrapper for ASP.NET.&lt;/p&gt;
    &lt;ul class=download&gt;
    &lt;li&gt;
      &lt;a href="http://hijax.net/BusinessLogic.web.zip"&gt;Download the ASP.NET 2.0 project for the sample.&lt;/a&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;
      BusinessLogic.web is Part of dotWeb - A .NET Business Framework for the web under development by beaconware ApS.&lt;/p&gt;
    &lt;p&gt;The aim of this project is to aid the developer in the proces of writing business logic for the right tier - that is the server - and in a compiled language. Most people can agree on that. This wrapper simplifies the proces of making a business entity &lt;b&gt;available&lt;/b&gt; on the client even though it really lives on the server.&lt;/p&gt;
  &lt;p&gt;BusinessLogic.web concerns itself with BUSINESS ONLY and it's very good at just that.&lt;/p&gt;
  &lt;p&gt;A very cool thing about this tool is, that you don't have to write web services anymore! Play with it!!&lt;/p&gt;
&lt;ul class=donors&gt;&lt;li&gt;&lt;a href=http://hijax.net&gt;Try online demo&lt;/a&gt;&lt;/ul&gt;

    &lt;h2&gt;Business Classes&lt;/h2&gt;
    
    &lt;p&gt;This is the Person class with the business logic layer.&lt;/p&gt;

    &lt;p&gt;It inherits from dotWeb.Core.Business.Entity, but that is just my own preference, the Entity class is optional, but make sure your business class supports IJsonFormattable, if you don't inherit from the Entity class!&lt;/p&gt;

    &lt;p&gt;Remember to put [Wrap] attributes on your class and on your public methods to make them available on the client. On the client side public properties will be wrapped like standard javascript properties, but if you want the getter or setter of a property available, like "set_PhoneNumber(value)" then you have to wrap them by specifying the [Wrap] attribute on the "set" symbol.&lt;/p&gt;
    
    &lt;pre&gt;
using System.Data.SqlTypes;
using dotWeb.Core.Scripting;
using dotWeb.Core.Business;

namespace MyCompany.Business.Logic {
  [Wrap]
  public class Person : Entity {
    protected SqlInt32 iId = SqlInt32.Null;
    protected SqlString sName = SqlString.Null;
    protected SqlString sPhoneNumber = SqlString.Null;

    public override SqlInt32 Id {
      get { return iId; }
      set { iId = value; }
    }

    public SqlString Name {
      get { return sName; }
      set { sName = value; }
    }

    public SqlString PhoneNumber {
      get { return sPhoneNumber; }
      [Wrap]
      set { 
        sPhoneNumber = value; 
      }
    }

    [Wrap]
    public void SetProperties(SqlString sName,
      SqlString PhoneNumber) {
      Name = sName;
      PhoneNumber = sPhoneNumber;
    }

    [Wrap]
    public void Save() {
      MyCompany.Data.SavePerson(this);
    }

    public Person(SqlInt32 iId) {
      Id = iId;
      MyCompany.Data.LoadPerson(this);
    }

    public Person() {
    }
  }
}
    &lt;/pre&gt;
    
    &lt;h2&gt;Data layer&lt;/h2&gt;

    &lt;p&gt;This i the data layer. For simplicity the data layer below uses the web server memory instead of a database. For any real life use, implement the database operations.&lt;/p&gt;
    
    &lt;pre&gt;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System;
using MyCompany.Business.Logic;
using dotWeb.Core.Scripting;

namespace MyCompany {
  [Wrap]
  public class Data {
    protected static Dictionary&amp;lt;Int32, Person&amp;gt; 
      oPersonTable = null;

    [Wrap]
    public static Dictionary&amp;lt;Int32, Person&amp;gt; PersonTable {
      get {
        if (oPersonTable == null) {
          //Implement your database loader here ...
          oPersonTable = new Dictionary&amp;lt;Int32, Person&amp;gt;();

          Person oPerson = new Person();
          oPerson.Id = 1;
          oPerson.Name = "Federico Ferris";
          oPerson.PhoneNumber = "555-6519845";
          oPersonTable[oPerson.Id.Value] = oPerson;

          oPerson = new Person();
          oPerson = new MyCompany.Business.Logic.Person();
          oPerson.Id = 2;
          oPerson.Name = "Kenneth Williamson";
          oPerson.PhoneNumber = "555-9877521";
          oPersonTable[oPerson.Id.Value] = oPerson;

          oPerson = new Person();
          oPerson.Id = 3;
          oPerson.Name = "Jess Nash";
          oPerson.PhoneNumber = "555-7498888";
          oPersonTable[oPerson.Id.Value] = oPerson;
        }
        return oPersonTable;
      }
      [Wrap]
      set {
        oPersonTable = value;
      }
    }

    public static void LoadPerson(
      MyCompany.Business.Logic.Person oPerson) {
      if (oPerson.Id.IsNull) {
        oPerson.Id = SqlInt32.Null;
        oPerson.Name = SqlString.Null;
        oPerson.PhoneNumber = SqlString.Null;
      }
      else {
        if (PersonTable.ContainsKey(oPerson.Id.Value)) {
          oPerson.Name = PersonTable[oPerson.Id.Value].Name;
          oPerson.PhoneNumber = 
            PersonTable[oPerson.Id.Value].PhoneNumber;
        }
      }
    }

    public static void SavePerson(
      MyCompany.Business.Logic.Person oPerson) {
      if (!oPerson.Id.IsNull) {
        //Implement your database updater here ...

        if (PersonTable.ContainsKey(oPerson.Id.Value)) {
          PersonTable[oPerson.Id.Value].Name = oPerson.Name;
          PersonTable[oPerson.Id.Value].PhoneNumber = 
            oPerson.PhoneNumber;
        }
        else {
          PersonTable[oPerson.Id.Value] = new Person();
          PersonTable[oPerson.Id.Value].Id = oPerson.Id;
          PersonTable[oPerson.Id.Value].Name = oPerson.Name;
          PersonTable[oPerson.Id.Value].PhoneNumber = 
            oPerson.PhoneNumber;
        }
      }
    }

    public static void DeletePerson(
      MyCompany.Business.Logic.Person oPerson) {
      if (!oPerson.Id.IsNull) {
        //Implement your database deleter here ...

        if (PersonTable.ContainsKey(oPerson.Id.Value)) {
          PersonTable.Remove(oPerson.Id.Value);
        }
      }
    }
  }
}
    &lt;/pre&gt;
    
    &lt;h2&gt;Javascript&lt;/h2&gt;

    &lt;ul class=download&gt;
    &lt;li&gt;
      &lt;a href="http://hijax.net/BusinessLogic.web.zip"&gt;Download the ASP.NET 2.0 project for the sample.&lt;/a&gt;
    &lt;/li&gt;
    &lt;/ul&gt;

    &lt;h3&gt;Calling a static property setter on MyCompany.Data&lt;/h3&gt;
    
    &lt;pre&gt;    
&amp;lt;script language=Jscript&amp;gt;

  MyCompany.Data.set_PersonTable(null);
  alert("Person table is now reset.");

&amp;lt;/script&amp;gt;
    &lt;/pre&gt;

    &lt;h3&gt;Reading Person properties.&lt;/h3&gt;
    
    &lt;pre&gt;   
&amp;lt;script language=Jscript&amp;gt;

  var oPerson = new MyCompany.Business.Logic.Person(1);
  alert("Person with Id 1 has the following name: "
   + oPerson.Name);

  var oPerson = new MyCompany.Business.Logic.Person(2);
  alert("Person with Id 2 has the following phone number: " 
    + oPerson.PhoneNumber);

  var oPerson = new MyCompany.Business.Logic.Person(3);
  alert("Person with Id 3 has the following name: "
    + oPerson.Name);

&amp;lt;/script&amp;gt;
    &lt;/pre&gt;

    &lt;h3&gt;Updating a Persons properties.&lt;/h3&gt;
    
    &lt;pre&gt;      
&amp;lt;script language=Jscript&amp;gt;

  var oPerson = new MyCompany.Business.Logic.Person(1);
  alert("Person with Id 1 has the following name: " 
    + oPerson.Name + " and phone number: " 
    + oPerson.PhoneNumber);
  
  oPerson.Name = "Brandon Carpenter";
  oPerson.PhoneNumber = "555-9872112";

  alert("Invoking method Person.Save()");
  oPerson.Save();
  
  var oPerson = new MyCompany.Business.Logic.Person(1);
  alert("Person with Id 1 now has the following name: " 
    + oPerson.Name + " and phone number: " 
    + oPerson.PhoneNumber);

&amp;lt;/script&amp;gt;
    &lt;/pre&gt;

    &lt;h3&gt;Invoking Person methods.&lt;/h3&gt;
    
    &lt;pre&gt;
&amp;lt;script language=Jscript&amp;gt;

  var oPerson = new MyCompany.Business.Logic.Person(2);

  alert("Person with Id 2 now has the following name: " 
    + oPerson.Name
    + " and phone number: " + oPerson.PhoneNumber);

  alert("Now invoking method " 
    + "Person.SetProperties('Russel Yeager', '555-987445')");
  oPerson.SetProperties('Russel Yeager', '555-987445');

  alert("Person with Id 2 now has the following name: "
    + oPerson.Name + " and phone number: " 
    + oPerson.PhoneNumber);
&amp;lt;/script&amp;gt;
    &lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-114501770200326202?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/114501770200326202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=114501770200326202' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/114501770200326202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/114501770200326202'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/04/businesslogicweb-net-business-logic.html' title='BusinessLogic.web - a .NET business logic wrapper for Javascript'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-114354477839969761</id><published>2006-03-28T03:15:00.000-08:00</published><updated>2006-03-28T04:32:30.863-08:00</updated><title type='text'>reboot8 "renaissance?"</title><content type='html'>&lt;div style="width:480px;overflow:hidden"&gt;&lt;img style="border-style:none" border=0 src=http://reboot.dk/images/header.png&gt;&lt;/div&gt;
&lt;p&gt;It's time for reboot8, which this year will take place in Copenhagen on June 1- 2 (Thursday and Friday). Same venue; better food; dinner, lounge and entertainment the first evening. More conversation; More Europeans doing interesting things; and still as informal and open an atmosphere as always, hopefully...&lt;/p&gt;

&lt;H2&gt;THE CHALLENGE&lt;/H2&gt;

&lt;p&gt;The theme for reboot8 is "renaissance?" - as in renaissance-question-mark. As in renaissance = rediscovery and revitalization. Question mark because it's a big word and a question to explore whether it's real, but renaissance because it seems as a healthier and more challenging perspective than the current bubble easy-reality buzzwords currently flowing around. So reboot8 is like reboot7 a journey into the interconnectedness of creation, participation, values, openness, decentralization, collaboration, complexity, technology, p2p, humanities, connectedness and many more areas. Applied towards us as individuals, citizens, teachers, culture workers, entrepreneurs, creators and change makers. &lt;/p&gt;

&lt;p&gt;It feels like we more should think a lot about the emerging new models and how we can help shape them, instead of focusing on how the new models are superior to the current models.&lt;/p&gt;

&lt;p&gt;Explore renaissance question mark at &lt;a href=http://reboot.dk/wiki/renaissance&gt;http://reboot.dk/wiki/Renaissance&lt;/a&gt;&lt;/p&gt;

&lt;H2&gt;THE PLATFORM&lt;/H2&gt;

&lt;p&gt;Unlike previous years there isn't a final speakers list or a black box creation model. reboot is a platform for bringing the European community together, a platform for conversations and relationships, a platform for sharing visions and meeting the people you didn't think you'd meet.&lt;/p&gt;

&lt;p&gt;So the platform is all yours, and this is an invitation to participate and help co-create reboot..:&lt;/p&gt;

- an invitation to submit topics you would like on the agenda for reboot
- an invitation to submit pointers to interesting people you know in your country that has something to contribute, and help us recruit them to come
- an invitation for your proposal to host or present if you've been doing some interesting thinking the last year or have created something that's worth sharing.
- an invitation for you to help make sure that we have the people that have open minds and are ready to make a difference at reboot. to connect europe, to widen the community, to add perspective.
&lt;p&gt;Help co-create reboot8 at &lt;a href=http://reboot.dk/wiki/Participate&gt;http://reboot.dk/wiki/Participate&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-114354477839969761?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/114354477839969761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=114354477839969761' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/114354477839969761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/114354477839969761'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/03/reboot8-renaissance.html' title='reboot8 &quot;renaissance?&quot;'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-114035634369560326</id><published>2006-02-19T05:39:00.000-08:00</published><updated>2006-04-13T19:42:14.776-07:00</updated><title type='text'>Ajax for Business Logic</title><content type='html'>&lt;p&gt;I created a &lt;b&gt;JavaScript&lt;/b&gt; Wrapper for my C# Business Logic classes. You specify which dll to "wrap" and the wrapper spits out javascript.&lt;/p&gt;

&lt;p&gt;The result is that you can write near-C# language in JavaScript! I have all the &lt;b&gt;public classes, constructors, public constants, public methods and public properties&lt;/b&gt; available client side in javascript.&lt;/p&gt;

&lt;p&gt;The methods and constructors are just "empty" functions that check if the correct number of parameters are specified and then perform a &lt;i&gt;synchronous&lt;/i&gt; web service call. The web service then invokes the constructor or method and returns the resulting value.&lt;/p&gt;

&lt;p&gt;This means that you don't need to write &lt;i&gt;hundreds of web services and web service methods&lt;/i&gt; when you need to interact with the business entities and business logic.&lt;/p&gt;

&lt;p&gt;In respect to security the wrapper only wraps &lt;b&gt;public&lt;/b&gt; classes and namespaces. And furthermore it checks that a &lt;b&gt;[Wrap]&lt;/b&gt; attribute is present.&lt;/p&gt;

&lt;p&gt;For even more security WSE provides a mechanism to digitally sign SOAP messages.&lt;/p&gt;

&lt;H2&gt;Examples:&lt;/H2&gt;

&lt;P&gt;Creating an instance of &lt;code&gt;Business.Logic.ContractSale&lt;/code&gt; using the constructor that takes an id as parameter, invoking &lt;code&gt;Validate()&lt;/code&gt; and &lt;code&gt;Accept(DateTime oDateAccepted)&lt;/code&gt; on the instance.&lt;/P&gt;

&lt;PRE&gt;
  var oContractSale = 
    new Business.Logic.ContractSale(iCSal_Id);

  if (oContractSale.Validate()) {
    oContractSale.Accept(new Date());
  }
  else {
    alert("Sales contract is not valid!");
  }
&lt;/PRE&gt;

&lt;P&gt;Creating a new instance of &lt;code&gt;Business.Logic.InvoiceSale&lt;/code&gt; setting properties and invoking method &lt;code&gt;Save()&lt;/code&gt; on the instance.&lt;/P&gt;

&lt;PRE&gt;
  var oInvoiceSale = 
    new Business.Logic.InvoiceSale();

  oInvoiceSale.DateInvoice = new Date();
  oInvoiceSale.Amount = 150;
  oInvoiceSale.Currency = Business.Logic.Currency.USD;
  oInvoiceSale.Save();
&lt;/PRE&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-114035634369560326?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/114035634369560326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=114035634369560326' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/114035634369560326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/114035634369560326'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/02/ajax-for-business-logic_19.html' title='Ajax for Business Logic'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-113994980187558086</id><published>2006-02-14T12:41:00.000-08:00</published><updated>2006-02-14T12:43:21.876-08:00</updated><title type='text'>Hijax.NET?</title><content type='html'>&lt;p&gt;I am considering a new name for OutPost, what do you think about &lt;b&gt;Hijax.NET&lt;/b&gt;?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-113994980187558086?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/113994980187558086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=113994980187558086' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/113994980187558086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/113994980187558086'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/02/hijaxnet.html' title='Hijax.NET?'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-113985692934126946</id><published>2006-02-13T10:48:00.000-08:00</published><updated>2006-03-03T01:06:44.426-08:00</updated><title type='text'>OutPost 1.2</title><content type='html'>&lt;P&gt;Version 1.2 now available.&lt;/P&gt;
&lt;ul class=download&gt;
&lt;li&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost12.zip"&gt;OutPost 1.2 (with source code)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="http://pbox.upfrontweb.com/OutPost.jpg" alt="A screenshot of The iGoogle Demo" width=400 height=235&gt;&lt;br&gt;Screenshot of "The iGoogle Demo" in the demo project&lt;/p&gt;
&lt;UL&gt;
&lt;LI&gt;Support for client event validation.
&lt;LI&gt;Support for server event validation.
&lt;LI&gt;Support for form validation.
&lt;LI&gt;Support for inputs with type=image.
&lt;LI&gt;Support for object databinding.
&lt;LI&gt;Full cross-browser support without need for ATLAS scripts.
&lt;LI&gt;Added Session support on first post back.
&lt;LI&gt;Added Response.Filter to take advantage of differences on first post back.
&lt;LI&gt;Support for Netscape.
&lt;LI&gt;Support for Opera.
&lt;LI&gt;Support for Opera.
&lt;LI&gt;Support for Visual Studio 2005
&lt;LI&gt;Support for both ASP.NET 1.1 and ASP.NET 2.0
&lt;LI&gt;Support for HTTPS/SSL
&lt;/UL&gt;
&lt;P&gt;Please give feedback!&lt;/P&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-113985692934126946?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/113985692934126946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=113985692934126946' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/113985692934126946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/113985692934126946'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2006/02/outpost-12.html' title='OutPost 1.2'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-113079426827369207</id><published>2005-10-31T13:18:00.000-08:00</published><updated>2005-10-31T14:38:35.120-08:00</updated><title type='text'>Executing multi-valued web service calls from javascript</title><content type='html'>&lt;P&gt;I'm currently working hard on a web based business system for a 
theatre agency here in Denmark. Client-side business logic communicates through web service calls with server-side business logic.&lt;/P&gt;

&lt;P&gt;I'm using the web service proxies that &lt;a href=http://ajaxaspects.blogspot.com/&gt;Matthias Hertels AJAX Engine&lt;/a&gt; generates,
but I was unable to use &lt;code&gt;ajax.Start&lt;/code&gt; to execute multi-valued calls.&lt;/P&gt;

&lt;P&gt;Maybe I overlooked something? :) Anyway, I came up with a fix for it...&lt;/P&gt;
 
&lt;P&gt;This an example of a multi-valued call:&lt;/P&gt;

&lt;PRE&gt;
  ...
  var Add = {
    delay: 200,
    prepare: function() { return [34, 23]; },
    call: proxies.AddService.Add,
    finish: function (p) {
      alert("Sum: " + p);
    },
    onException: proxies.alertException
  };

  ajax.Start(Add);
  ...
&lt;/PRE&gt;
 
&lt;P&gt;I changed some lines in &lt;code&gt;Ajax.js&lt;/code&gt;. After this:&lt;/P&gt;

&lt;PRE&gt;
      ...      
      // start the call
      ca.call.func = ajax.Finsh;
      ca.call.onException = ajax.Exception;
&lt;/PRE&gt;

&lt;P&gt;I added this:&lt;/P&gt;

&lt;PRE&gt;
      // multi-valued call (new)
      if ((typeof(data)=="object") &amp;&amp; (data!=null) &amp;&amp; data.length) {
        ca.args = new Object();
        var aArg = new Array();
        for (var i = 0; i&amp;lt;data.length; i++) {
          ca.args["a" + i] = data[i];
          aArg[aArg.length] = "a" + i;
        }
        with (ca.args) {
          eval("ca.call(" + aArg.join(",") + ")");
        }
      }
      // single-valued call
      else { 
        ca.call(data);
      }      
      ...
&lt;/PRE&gt;

&lt;P&gt;And it worked. I hope you can use this.&lt;/P&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-113079426827369207?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/113079426827369207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=113079426827369207' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/113079426827369207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/113079426827369207'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/10/executing-multi-valued-web-service.html' title='Executing multi-valued web service calls from javascript'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-112975792103733902</id><published>2005-10-19T14:37:00.000-07:00</published><updated>2005-10-19T14:38:41.043-07:00</updated><title type='text'>OutPost: Near future roadmap</title><content type='html'>&lt;p&gt;As soon as I have a version of OutPost that is ASP.NET version independent (I'm working on that now) I'll optimize more on the amount of data sent back to the client.

&lt;P&gt;I have just added support for Netscape 8 and Opera 8.5 in my development version, and I'll post a new beta version of that soon. I also got OutPost working nicely with the Personal Web Starter Kit for ASP.NET 2.0 RC.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-112975792103733902?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/112975792103733902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=112975792103733902' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112975792103733902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112975792103733902'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/10/outpost-near-future-roadmap.html' title='OutPost: Near future roadmap'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-112941086214221845</id><published>2005-10-15T14:07:00.000-07:00</published><updated>2005-10-17T05:21:21.290-07:00</updated><title type='text'>OutPost 1.1 beta (ASP.NET 2.0 only)</title><content type='html'>&lt;p&gt;&lt;b&gt;Great news for beta testers: &lt;/b&gt;You can download the 1.1 beta ASP.NET 2.0 version of OutPost now.

&lt;ul class=download&gt;&lt;li&gt;
&lt;a href=http://pbox.upfrontweb.com/OutPost11beta.zip&gt;OutPost 1.1 beta (ASP.NET 2.0 only)&lt;/a&gt;
&lt;/ul&gt;

&lt;p&gt;It doesn't work in FireFox yet, because I haven't been able to make the tags behave like they should.

&lt;p&gt;Here are some of the new features / bug fixes:

&lt;p&gt;
1.1.000 - 20051014 1700 twj&lt;br&gt;
Support for HTTPS/SSL.&lt;br&gt;
Support for Visual Studio 2005 Release Candidate.&lt;br&gt;
&lt;br&gt;
1.0.002 - 20051007 1125 twj&lt;br&gt;
Bug fixed in javascript Serializer: Unicode characters were not escaped properly.&lt;br&gt;
Optimization of the JavaScript property by using StringBuilder.&lt;br&gt;
Default values are stored before PostBack and restored afer PostBack.&lt;br&gt;
&lt;br&gt;
1.0.001 - 20051004 1825 twj&lt;br&gt;
Bug fixed in constructor: PartsNeeded is only initialized as a StringArray if the "PartsNeeded" header is set.&lt;br&gt;
Bug fixed in window_onload function: Script error if no forms present on page.&lt;br&gt;
Added version comment to client-framework javascript.&lt;br&gt;
&lt;br&gt;
1.0.000 - 20051003 0149 twj&lt;br&gt;
Initial article release.&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-112941086214221845?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/112941086214221845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=112941086214221845' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941086214221845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941086214221845'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/10/outpost-11-beta-aspnet-20-only.html' title='OutPost 1.1 beta (ASP.NET 2.0 only)'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-112941152275774034</id><published>2005-10-12T14:24:00.000-07:00</published><updated>2005-10-15T14:25:22.756-07:00</updated><title type='text'>OutPost: Performance Tuning and Optimization</title><content type='html'>The same principles for Performance Tuning and Optimization apply when developing with OutPost. You optimize by taking advantage of the view-state, page level caching, page fragment caching, application caching, session caching and the web server Cache.&lt;br&gt;&lt;br&gt;With OutPost you can actually get further performance improvements: &lt;br&gt;- Splitting up your page and having more web forms on the same page, like in "The iGoogle Demo", is a great idea. &lt;br&gt;- Finding the balance of when to use the view-state and when not to is also important and would often require you to test your application and analyze the load times to find the right settings. &lt;br&gt;- Setting the IDs of the HTML elements that frequently get updated is a good idea, because OutPost compares the innerHTML of elements with IDs.&lt;br&gt;&lt;br&gt;I'll grant you that AJAX is much nicer to the server. But I would say that OutPost is much nicer to the developer &lt;img src="http://www.codeproject.com/script/images/smiley_smile.gif" align=absmiddle&gt; &lt;br&gt;&lt;br&gt;I like the simple structure of ASP.NET Web Forms and the way that you can develop ASP.NET controls for different browsers (with or without DHTML, depending on the capabilities of the browser).&lt;br&gt; &lt;br&gt;The improvements to ASP.NET in upcoming versions (e.g. the view-state) will also have impact on the performance in OutPost web applications. &lt;br&gt;&lt;br&gt;The improvements that you mention in ASP.NET 2.0 that you can write asynchronous pages will also work in combination with OutPost. &lt;br&gt;&lt;br&gt;ATLAS will also work in combination with OutPost to provide extra RIA features to up-level browsers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-112941152275774034?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/112941152275774034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=112941152275774034' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941152275774034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941152275774034'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/10/outpost-performance-tuning-and.html' title='OutPost: Performance Tuning and Optimization'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-112941147393334211</id><published>2005-10-11T14:24:00.000-07:00</published><updated>2005-10-15T14:24:33.933-07:00</updated><title type='text'>OutPost: Future Improvements</title><content type='html'>I am working on an easy way to make web service calls from JavaScript and I will include that in OutPost, so that you don't have create an invisible web form with text boxes and buttons if you want to call the server. I think it will be inspired heavily by ATLAS. I would really like to include more ATLAS features in OutPost.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-112941147393334211?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/112941147393334211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=112941147393334211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941147393334211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941147393334211'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/10/outpost-future-improvements.html' title='OutPost: Future Improvements'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-112941144446621092</id><published>2005-10-10T14:20:00.000-07:00</published><updated>2005-10-15T14:24:04.466-07:00</updated><title type='text'>OutPost: How I got the Idea</title><content type='html'>It is a novel solution. I got the idea, while I was developing the framework for &lt;a href="http://www.beaconware.com/top/produkter/upfront"&gt;a web site editor called UpFront&lt;/a&gt; in 2002, where the user designs his pages by inserting text, images, data lists, web forms and navigation menus on the pages.&lt;br&gt;&lt;br&gt;The language was ASP (JavaScript) on the server-side and JavaScript on the client. I had two parallel frameworks to create data lists, web forms and navigation menus (one on the client-side and one on the server-side). The client-side framework was used when dynamically creating or updating the properties of a data list, web form or navigation menu in the editor (with heavy use of DHTML and XmlHttp calls to retrieve dataset in JSON - developed on top of JSRS). The server-side framework was used when rendering HTML on the first page load.&lt;br&gt;&lt;br&gt;I found out that I could trash the client-side framework by calling an ASP page that returned the HTML and JavaScript needed over XmlHttp. This was a huge improvement i productivity, because I had one framework less to maintain and I could develop new "controls" faster.&lt;br&gt;&lt;br&gt;This solution also gave me the advantage that I could gradually convert to C#-compiled code and I did so by calling a .NET web service over XmlHttp for the data list and navigation menus to start of with, and I still used a page (now an ASP.NET page) to render data lists and navigation menus. Now I could take advantage of the ASP.NET DataGrid for my lists, but in order to make it work properly I had to support the view-state and the server-events, so I examined the headers and the body of post backs to ASP.NET pages (using Fiddler and other HTTP debugging tools) and I was able to simulate it. So now I had my data lists and navigation menus rendered like stand-alone .NET pages with support for State Management, Server Events, Page-Level Caching, Page Fragment Caching, Session, Application and Data Cache. The HTML that the page generated contained the view-state, but I didn't have to return that to the client, since it's not used for anything on the client, so I stored it in Application together with the HTML. In that way I could compare HTML from request to request and didn't have to send more than necessary to the client. The view-state was combined with the form data from the client to make the request to the ASPX page.&lt;br&gt;&lt;br&gt;So that's how I got the idea. As you can see I started out with Remote Scripting and DHTML (AJAX!). I moved away from that primarily to get productivity gains. OutPost is cross-browser compatible because it relies on ASP.NET controls that are cross-browser compatible. That also means that when you use OutPost on an up-level browser JavaScript will be transmitted on the first page load to take advantage of the capabilities in the client browser, and less HTML will be transmitted on post backs or no post backs will be necessary at all. So it will not be a screen scraping on up-level browsers. If the client browser is a downlevel-browser more HTML will be transmitted. In the examples in the demo project I have set the Page attribute clienttarget="downlevel" to force it to make a post back, but you can remove that attribute and no post backs will be made.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-112941144446621092?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/112941144446621092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=112941144446621092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941144446621092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941144446621092'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/10/outpost-how-i-got-idea.html' title='OutPost: How I got the Idea'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-112941163818902422</id><published>2005-10-09T14:26:00.000-07:00</published><updated>2005-10-15T14:27:18.190-07:00</updated><title type='text'>OutPost: Creating Interactive Web Applications</title><content type='html'>When you are creating interactive web applications with AJAX (any AJAX framework), you need a solid understanding of the DOM and CSS in different browsers. DHTML can be a challenge for any developer - you have to test your application rigorously in different browsers. And browsers do change.

You have to write the DHTML for your controls and you have to make it cross-browser compatible yourself. ATLAS lends the developer a hand by introducing its layers of DOM compatibility. The DOM is extended by adding methods to the document and window element (as I describe it in the article). And that is great if you need to write DHTML!

But with OutPost you don't! You just have to use stardard ASP.NET controls that are able to output HTML for downlevel browsers. If the browser is up-level it outputs HTML+JavaScript, and if the browser is down-level is outputs HTML.

If you installed the demo project, you can try this out by removing the clienttarget="downlevel" attribute in the Page directive of Validator7.aspx or Validator8.aspx. You'll then notice that with up-level browsers fewer XmlHttp-calls are now made, because the validation is done with JavaScript.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-112941163818902422?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/112941163818902422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=112941163818902422' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941163818902422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112941163818902422'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/10/outpost-creating-interactive-web.html' title='OutPost: Creating Interactive Web Applications'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-112850664875046325</id><published>2005-10-05T03:01:00.000-07:00</published><updated>2005-10-17T03:19:34.393-07:00</updated><title type='text'>OutPost: Post Back Over XmlHttp</title><content type='html'>&lt;p&gt;Perform real Post Backs of ASP.NET Web Forms without reloading the entire page.&lt;br&gt;
Keywords: AJAX, XmlHttp, WebForms, Post Back, DHTML, Web Service, OutPost.

&lt;ul class=download&gt;
&lt;li&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost11beta.zip"&gt;Download OutPost 1.1 beta for ASP.NET 2.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pbox.upfrontweb.com/OutPost_demo.zip"&gt;Download OutPost 1.0 for ASP.NET 1.1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://pbox.upfrontweb.com/OutPost.jpg" alt="A screenshot of The iGoogle Demo" width=400 height=235&gt;&lt;br&gt;Screenshot of "The iGoogle Demo" in the demo project&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;This article assumes that you are familiar with ASP.NET WebForms. 
You might also want to know the basics about AJAX. This is a quote from &lt;a href="http://en.wikipedia.org/wiki/AJAX"&gt;Wikipedia on AJAX&lt;/a&gt;:

&lt;blockquote&gt;
&lt;i&gt;
&lt;p&gt;Ajax applications look almost as if they reside on the user's machine, rather than across the Internet on a server. The reason: pages get updated, not entirely refreshed.

&lt;p&gt;“Every user action that normally would generate an HTTP request takes the form of a JavaScript call to the Ajax engine instead”, wrote Jesse James Garrett, in the essay that first defined the term. “Any response to a user action that doesn’t require a trip back to the server — such as simple data validation, editing data in memory, and even some navigation — the engine handles on its own. If the engine needs something from the server in order to respond — if it’s submitting data for processing, loading additional interface code, or retrieving new data — the engine makes those requests asynchronously, usually using XML, without stalling a user’s interaction with the application.”

&lt;P&gt;Traditional web applications essentially submit forms, completed by a user, to a web server. The web server responds back by sending a new web page. Because the server must submit a new page each time, applications run more slowly and awkwardly than their native counterparts.

&lt;P&gt;Ajax applications, on the other hand, can send requests to the web server to retrieve only the data that is needed, usually using SOAP or some other XML-based web services dialect. On the client, JavaScript processes the web server response. The result is a more responsive interface, since the amount of data interchanged between the web browser and web server is vastly reduced. Web server processing time is also saved, since much of it is done on the client.
&lt;/I&gt;
&lt;/blockquote&gt;

&lt;h2&gt;AJAX is a maintenance nightmare&lt;/h2&gt;

&lt;p&gt;Today you &lt;i&gt;have&lt;/i&gt; to 
create web applications that work in both IE and Firefox, and that is definitely doable but also pretty time consuming and a maintenance nightmare.
 
&lt;p&gt;AJAX has become very popular, because it answers a need for speed and responsiveness in web applications and there has also been the "Google" effect: 

&lt;p&gt;&lt;i&gt;- "We create interactive web applications like Google does and they use AJAX too"&lt;/i&gt;,

&lt;p&gt;yeah, but it is not so cool, if you use 95% of the time on testing in different browsers. 

&lt;p&gt;&lt;B&gt;AJAX falls short on two major points:&lt;/b&gt; It has no support of the state management in ASP.NET Web Forms and it has no support for cross-browser
web applications. The goal of this article is to solve these two issues. 

&lt;h2&gt;Example&lt;/h2&gt;

&lt;p&gt;Lets say you have a tree-structure displayed to the user (like in Windows Explorer) and you only want to
retrieve and display the sub-folders when the user expands a folder in the tree. 

&lt;p&gt;&lt;b&gt;With AJAX&lt;/b&gt; you would call a web service to retrieve an array containing the subfolder names, 
links and icons and create the tree nodes using DHTML. You would have to create the web service methods, write cross-browser javascript to make
it work and have hidden fields in your ASP.NET WebForm containing the state of the control.

&lt;p&gt;&lt;B&gt;What OutPost does&lt;/B&gt; is to perform a &lt;i&gt;real Post Back&lt;/i&gt; through a Web Service that also manages the view-state (and keeps it on the web server).
The &lt;code&gt;InnerHtml&lt;/code&gt; of the modified elements are sent back to the client and displayed in the browser. In that way the whole process is generalized
and you don't need to create Web Service methods, DHTML javascripts or add hidden fields for your ASP.NET Controls.

&lt;p&gt;So obviously you get considerable productivity gains by using OutPost to AJAX-enable your web applications.

&lt;h3&gt;What makes OutPost unique?&lt;/h3&gt;

&lt;p&gt;OutPost is a new angle on AJAX. Other AJAX frameworks use specifically tailored Web Services, that you have
to write yourself to return the data you need. And none of the frameworks fully support the benefits of the ASP.NET Framework.
With AJAX you have to re-think and re-write your code.

&lt;h4&gt;Unique advantages of OutPost&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;A single &lt;code&gt;.js&lt;/code&gt; include file is enough for OutPost.
&lt;li&gt;OutPost converts any ASP.NET WebForm into an AJAXed WebForm without any modifications to the code.
&lt;li&gt;It has cross-browser support built-in.
&lt;li&gt;The Post Backs are 100% real and server-side events are triggered, as you'd expect them to trigger.
&lt;li&gt;Multiple server-side WebForms (&lt;code&gt;.aspx&lt;/code&gt;-pages) are supported side by side on the same page.
&lt;li&gt;Excess traffic between client and server is eliminated (the view-state stays on the server and only modified HTML is sent back to the client).
&lt;li&gt;A lightweight javascript client-framework makes it possible to add, remove and Post Back WebForms by script.
&lt;/ul&gt;

&lt;h4&gt;Other OutPost features&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Output caching is supported on WebForm-level.
&lt;li&gt;Unicode characters are supported.&lt;li&gt;A WebForm has its own Session.
&lt;li&gt;No custom controls are needed.
&lt;li&gt;Main pages and WebForms can be designed in VS.NET.
&lt;/ul&gt;

&lt;h3&gt;OutPost-enabling a single WebForm&lt;/h3&gt;

&lt;p&gt;The decision to add "AJAX" to your pages is not a question of "do we have the time and skill to implement it". Instead it becomes a design question.

&lt;P&gt;To add OutPost and AJAX-enable a WebForm, all you need is to write the following in the beginning of your &lt;code&gt;.aspx&lt;/code&gt; file:
&lt;/P&gt;

&lt;PRE&gt;
  &amp;lt;script src="/OutPost/OutPost.js.aspx" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/PRE&gt;

&lt;p&gt;But let us just zoom out for a second:

&lt;h2&gt;Background&lt;/h2&gt;

&lt;p&gt;When developing interactive applications for the web, you have different models to use, and two of 
them are shown below. They can be combined in many ways, but if they are not combined the following 
is a non-pre-emptive comparison of their advantages and disadvantages:

&lt;h3&gt;ASP.NET WebForms&lt;/h3&gt;
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;FAST AND SAFE:&lt;/b&gt; Compiled code, type safe code model.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;OPEN OOP MODEL:&lt;/b&gt; Object oriented programming model, open extendable classes, reusable code.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;FRAMEWORK:&lt;/b&gt; Has an extensible framework with a fair amount of rapid development tools and web controls ready to use.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;STATE MANAGED:&lt;/b&gt; It manages the state for you using viewstate post backs.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;SERVER-EVENTS:&lt;/b&gt; An event model takes care of the communication between client and server.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;CROSS-BROWSER:&lt;/b&gt; The HTML and javascript it produces automatically match the capabilities of the target browser.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;CACHED OUPUT:&lt;/b&gt; Pages, controls and datasets can be cached in a variety of ways.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;FAST STARTUP:&lt;/b&gt; Only the HTML needed for displaying the current page is transmitted to the client.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;&lt;b&gt;HEAVY TRAFFIC:&lt;/b&gt; When posting back, the whole web form including the viewstate is uploaded to the server and the whole page is then sent back to the client.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;&lt;b&gt;RELOADS:&lt;/b&gt; When posting back the whole page is refreshed and especially on slow connections and or slow cpu's this makes the page flicker.&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
  
&lt;h3&gt;AJAX&lt;/h3&gt;
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;LIGHT TRAFFIC:&lt;/b&gt; State is not transmitted back to the server, only the needed data is transmitted&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;&lt;b&gt;NO RELOADS:&lt;/b&gt; The page is updated by using DHTML (manipulating the DOM with javascript).&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;&lt;b&gt;NO SERVER-EVENTS:&lt;/b&gt; Communication with the server is done by directly calling different web service methods.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;&lt;b&gt;SLOW AND UNSAFE:&lt;/b&gt; Jscript is not a compiled language and testing is pretty difficult on some devices.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;&lt;b&gt;SLOW STARTUP:&lt;/b&gt; Huge amounts of javascript is usually needed for client controls and these files are sent to the client on startup.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;&lt;b&gt;NOT CROSS BROWSER:&lt;/b&gt; Making sure the DHTML is cross browser is completely in the hands of the developer.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;&lt;b&gt;NO FRAMEWORK:&lt;/b&gt; You have to put together your own client-control framework to manipulate the DOM.&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;h2&gt;OutPost - The best of both worlds&lt;/h2&gt;

&lt;p&gt;In OutPost the advantages of ASP.NET WebForms and AJAX are combined. OutPost takes care of the following:

&lt;ol&gt;
&lt;li&gt;Need for cross-browser DHTML is eliminated.
&lt;li&gt;A real Post Back is executed and server-side events are fired.
&lt;li&gt;Excess traffic is eliminated.
&lt;li&gt;Page reloads are eliminated.
&lt;/ol&gt;
 
&lt;p&gt;That easy, right? Yes, let's take it step by step.

&lt;h2&gt;Step by step&lt;/h2&gt;

&lt;p&gt;The steps below describe the life of a Post Back when using OutPost:

&lt;ol&gt;
&lt;li&gt;&lt;h4&gt;Need for cross-browser DHTML is eliminated&lt;/h4&gt;
&lt;P&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;A main page loads the Web Form Page and in that process (on the server) the HTML and ViewState are stored for later use (it is used again on the server 
when posting back the WebForm). Also the needed link(s) to javascript file(s) are inserted in the HEAD section of the HTML (extra cross-browser compatibility
layer scripts are added if necessary).&lt;/p&gt;
&lt;p&gt;When loading a WebForm, you can decide whether you want all the HTML or only the outerHTML of the form. If you want several forms loaded onto
the same main page, you would only need the outerHTML of each form and add that, where you'd like on the page (as long as it is not inside the page's own web form). &lt;/p&gt;
&lt;p&gt;If you load a single WebForm you could go for the HTML of the whole page and simply let that be the contents of the main page. The main page does not necessarily need 
to have its own web form.&lt;/p&gt;
&lt;li&gt;The above is optional and you can insert the javascript link in your code yourself and use the &lt;outpost:script&gt; server-controls to add the cross-browser 
compatibility layers if needed. 
&lt;p&gt;The compatibility layers are added by the files &lt;code&gt;AtlasCompat.js&lt;/code&gt; and &lt;code&gt;AtlasCompat2.js&lt;/code&gt; from &lt;a href="http://atlas.asp.net/"&gt;Atlas&lt;/a&gt; (the Microsoft ASP.NET 2.0 AJAX platform) 
and they ensure that the OutPost runtime works the same in all browsers. For example on the window and the document elements the attachEvent and detachEvent 
functions are added, so the DHTML in the OutPost runtime can be the same.
&lt;p&gt;If you don't use a main page, the HTML structure and the ViewState of the first call will not be
stored on the server and the first post back will have to send the ViewState to the server and the inner HTML of the whole web form will also be sent back to the 
client on the first Post Back.&lt;/p&gt;&lt;/ul&gt;
&lt;li&gt;&lt;h4&gt;A real Post Back is executed and server-side events are fired&lt;/h4&gt;
&lt;p&gt;The PostBack of the form is replaced by out-of-band calls to a .NET Web Service. The calls are made from javascript without reloading the page. This is done by posting a 
SOAP-envelope to the Web Service using &lt;a href="http://en.wikipedia.org/wiki/XMLHttpRequest"&gt;XmlHttp&lt;/a&gt;. The SOAP-envelope contains the Uri of the WebForm Page 
(the action attribute of the form element) and the contents of the input fields in the WebForm (but not the ViewState).&lt;/p&gt;
&lt;p&gt;The Web Service then executes the real Post Back using HttpWebRequest and HttpWebResponse. Headers containing user agent, language and session cookie are sent 
on to the WebForm Page.&lt;/p&gt;
&lt;li&gt;&lt;h4&gt;Excess traffic is eliminated&lt;/h4&gt;
&lt;p&gt;The HTML read from the HttpWebResponse is parsed and the tags/elements that have an ID gets picked out and put into a tree structure. This step only works if the HTML
structure is correct. If the structure is not correct the inner HTML of the whole web form is sent back to the client (not the ViewState though).&lt;/p&gt;
&lt;p&gt;The HTML tree structure of the new post back is compared to the HTML tree structure of the last post back. This is done in a bottom-up way, so first the contents of the
form without any inner HTML of sub nodes are compared. If no differences found, the inner HTML of the next sub nodes (with the same id and id-index) from each tree 
are compared without the inner HTML of their sub nodes. And so forth.&lt;/p&gt;
&lt;li&gt;&lt;h4&gt;Page reloads are eliminated&lt;/h4&gt;
&lt;p&gt;The inner HTML of the elements found to be different in the previous step are returned to the client. The DOM is updated, element by element, using cross browser DHTML.
&lt;p&gt;It might seem as a bit of a crude way to just send the modified innerHTML fragments back to the client, but it really makes sense when developing 
cross-browser web applications.
&lt;/p&gt;
&lt;/ol&gt;

&lt;h2&gt;Using the code&lt;/h2&gt;

&lt;h3&gt;A single WebForm&lt;/h3&gt;

&lt;P&gt;To add OutPost and AJAX-enable a WebForm, all you need is to write the following in the beginning of your &lt;code&gt;.aspx&lt;/code&gt; file:
&lt;/P&gt;

&lt;PRE&gt;
  &amp;lt;script src="/OutPost/OutPost.js.aspx" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/PRE&gt;

&lt;h3&gt;Using a main page to load the WebForm&lt;/h3&gt;

&lt;P&gt;To load a page from a main page and OutPost-enable it you write the following 
  in your &lt;CODE&gt;Page_Load&lt;/CODE&gt; method:
&lt;/P&gt;

&lt;PRE lang="cs"&gt;    private void Page_Load(object sender, System.EventArgs e) {
      Page.Controls.Add(OutPost.Core.OutPost.GetLiteralControl(ResolveUrl("Validator7.aspx")));
    }
&lt;/PRE&gt;

&lt;P&gt;This (when placed in the top) adds cross-browser scripts on demand, based on 
  the client User-Agent:
&lt;/P&gt;

&lt;PRE&gt;
  &amp;lt;%@ Register TagPrefix="outpost" Namespace="OutPost.Controls" Assembly="OutPost" %&amp;gt;
  &amp;lt;outpost:script Runat="server" Path="~/ScriptLibrary/AtlasCompat.js" Browsers="Netscape,Mozilla,Firefox,Apple,Safari,Mac" /&amp;gt;
  &amp;lt;outpost:script Runat="server" Path="~/ScriptLibrary/AtlasCompat2.js" Browsers="Apple,Safari,Mac" /&amp;gt;
&lt;/PRE&gt;

&lt;h3&gt;Having two forms on the same page that depend on each other&lt;/h3&gt;

&lt;P&gt;Using javascript it is possible to let two forms depend on each other:

&lt;PRE&gt;  &amp;lt;script type="text/javascript"&amp;gt;
    //OutPost7.aspx

    function document_onkeyup() {
      if (event.srcElement==Forms[0].TextBox1) {
        Forms[1].TextBox1.value = event.srcElement.value;
      }
    }

    function document_onclick() {
      if (event.srcElement==Forms[0].Button1) {
        Forms[1].Button1.bClicked = true;
        Forms[1].doPostBack('','');
      }
    }
    
    document.attachEvent("onclick",document_onclick);
    document.attachEvent("onkeyup",document_onkeyup);
  &amp;lt;/script&amp;gt;
&lt;/PRE&gt;

&lt;h3&gt;Using the Client Framework&lt;/h3&gt;

&lt;P&gt;The following example shows how you can dynamically add, remove and Post Back 
different forms on a page (See "The iGoogle Demo" in the demo project and the 
screen shot from the demo in the beginning of this article).

&lt;PRE&gt;
  //RssFeed.js - "The iGoogle Demo"

  function DeleteBox() {
    var oNodeForm = null;
    if (oEventNode) {
      oNodeForm = misc_getForm(oEventNode);
      oEventNode = null;
    }
    if (oNodeForm!=null) {
      oNodeForm.parentNode.parentNode.removeChild(oNodeForm.parentNode);
      Forms[oNodeForm.iIndex] = null;
    }
    var sAction = unescape(oNodeForm.action);
    FormMain.bAddBox = false;
    FormMain.doPostBack("oButtonDelete",sAction);
  }
  
  function AddBox() {
    var sUri = "/OutPost/Demo/RssFeed.aspx?rss="+escape(document.getElementById('FormMain').oTextBoxAddRssUri.value);
    
    for (var i in Forms) {
      if ((Forms[i]!=null) &amp;amp;&amp;amp; (unescape(Forms[i].action)==unescape(sUri))) {
        alert("The feed has already been added");
        return;
      }
    }
  
    var oNodePanel = document.createElement("DIV");
    oNodePanel.className = "cPage";
    
    var oNodeColumn = document.getElementById("oTableCell2");
    if (document.getElementById("oTableCell1").childNodes.length&amp;lt;oNodeColumn.childNodes.length) {
      oNodeColumn = document.getElementById("oTableCell1");
    }
    if (document.getElementById("oTableCell3").childNodes.length&amp;lt;oNodeColumn.childNodes.length) {
      oNodeColumn = document.getElementById("oTableCell3");
    }
    
    oNodeColumn.appendChild(oNodePanel);
    
    var oNodeForm = createForm("Form1", sUri, AddBox_onerror);
    oNodePanel.appendChild(oNodeForm);
    document.getElementById('FormMain').oTextBoxAddRssUri.value = "";
  }
  
  function AddBox_onerror() {
    alert("Error adding RSS feed");
  }
  
  function FormMain_onsuccess() {
    this.base_onsuccess();
    if (this.bAddBox!=false) {
      AddBox();
    }
    this.bAddBox = true;
  }
  
  function window_onload() {
    FormMain.onsuccess = FormMain_onsuccess;
  }
  
  window.attachEvent("onload", window_onload);
&lt;/PRE&gt;

&lt;h2&gt;The Future of OutPost&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Making it possible to send back changes on a smaller scale (like only setting the value of an input or only changing one option in a dropdown list).
&lt;li&gt;I would like to incorporate simple AJAX behaviour, so that you can interact with business logic on the web server.
&lt;li&gt;Solving the Bookmark issue. It is not possible to bookmark a WebForm page and I'm trying to find a solution to that.
&lt;li&gt;Solving the Back-button issue. It is not possible to use Back-Button and I'm trying to find a solution to that also.
&lt;/ul&gt;

&lt;h2&gt;History&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sep 2005 - OutPost version 1.0 - Added cross-browser support, lightweight client-framework, 
&lt;li&gt;May 2005 - OutPost version 0.5 - Single web form supported, IE only.
&lt;li&gt;Nov 2004 - First initial testing performed.
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-112850664875046325?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/112850664875046325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=112850664875046325' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112850664875046325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112850664875046325'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/10/outpost-post-back-over-xmlhttp.html' title='OutPost: Post Back Over XmlHttp'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-112676545037495269</id><published>2005-09-14T23:24:00.000-07:00</published><updated>2005-10-06T04:22:55.920-07:00</updated><title type='text'>OutPost: I'm writing an article about the project</title><content type='html'>&lt;P&gt;I am working on an article about OutPost, a very simple way to achieve "AJAX"-style behaviour in your ASP.NET applications&lt;/P&gt;

&lt;P&gt;The basics&lt;/P&gt;

&lt;UL&gt;
&lt;LI&gt;The viewstate is properly updated&lt;/LI&gt;
&lt;LI&gt;Session works&lt;/LI&gt;
&lt;LI&gt;Unicode characters are supported&lt;/LI&gt;
&lt;LI&gt;Server-side events work&lt;/LI&gt;
&lt;/UL&gt;

&lt;P&gt;In order to make it easy to use, you would also need the following&lt;/P&gt;

&lt;UL&gt;
&lt;LI&gt;No custom controls are needed&lt;/LI&gt;
&lt;LI&gt;Pages can be designed as normal&lt;/LI&gt;
&lt;/UL&gt;

&lt;P&gt;To make it really fun and powerful to use, what about&lt;/P&gt;

&lt;UL&gt;
&lt;LI&gt;Multiple forms on same page&lt;/LI&gt;
&lt;LI&gt;Multiple aspx pages on the same page&lt;/LI&gt;
&lt;/UL&gt;

&lt;P&gt;All the above is already working now, so what about the future?&lt;/P&gt;

&lt;UL&gt;
&lt;LI&gt;Automatic dotfuscating of javascript and html&lt;/LI&gt;
&lt;LI&gt;Minimizing transfer by only transmitting difference between posts&lt;/LI&gt;
&lt;/UL&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-112676545037495269?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112676545037495269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/112676545037495269'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/09/outpost-im-writing-article-about.html' title='OutPost: I&apos;m writing an article about the project'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-111873981008105882</id><published>2005-06-14T01:54:00.000-07:00</published><updated>2005-10-05T02:18:47.550-07:00</updated><title type='text'>Writing typesafe SQL-WHERE clauses</title><content type='html'>&lt;DIV&gt;I have written a code generator, that generates C# classes based on the tables and views in a database. It had for some time irritated me that even though everything was now neatly packaged in a data layer and an entity relation layer I still needed the occasional SQL-WHERE clause here and there. And as you know they never result in compile time errors, but instead in runtime errors, which is worse... So I wanted the compiler to catch me if I wrote a syntax incorrect SQL-WHERE clause, instead of getting a runtime error, when a user reached the specific page and state of things.&lt;/DIV&gt;
&lt;DIV&gt;Also when I modified the database, I wanted the compiler to check the SQL-WHERE clauses for me, which can be a tideous chore to do manually. So I came up with this solution, that works best in combination with a code generator, because then you'll have complete syncronisation with the columns and datatypes to use.&lt;/DIV&gt;
&lt;H2&gt;Features&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;Support for != and == operators
&lt;LI&gt;Support for &amp;&amp; and || binary operators
&lt;LI&gt;Support for int datatype
&lt;LI&gt;Support for string datatype
&lt;/UL&gt;
&lt;H2&gt;Examples&lt;/H2&gt;
&lt;DIV&gt;Note: The examples show how to create Filter instances. I use my code generator to do this for me. It creates a filter instance for each column. If I refer to a column that has been deleted or renamed in the database the compiler will catch this.&lt;/DIV&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;CODE&gt;Filter.IntFilter iEmpl_Id = new Filter.IntFilter("Empl_Id");
&lt;BR&gt;string sSQLWhere = (iEmpl_Id=="A text").ToString();&lt;/CODE&gt;
&lt;I&gt;Results in a compile time error.&lt;/I&gt;
&lt;LI&gt;&lt;CODE&gt;Filter.IntFilter iEmpl_Id = new Filter.IntFilter("Empl_Id");
&lt;BR&gt;string sSQLWhere = (iEmpl_Id==13).ToString();&lt;/CODE&gt;
&lt;BR&gt;&lt;I&gt;Results in the string &lt;CODE&gt;"Empl_Id=13"&lt;/CODE&gt;.&lt;/I&gt;
&lt;LI&gt;&lt;CODE&gt;Filter.StringFilter sEmpl_NameFirst = new Filter.StringFilter("Empl_Name");
&lt;BR&gt;Filter.IntFilter iEmpl_Id = new Filter.IntFilter("Empl_Id");
&lt;BR&gt;string sSQLWhere = (iEmpl_Id==13 || iEmpl_Id!=10&amp;&amp;sEmpl_NameFirst=="D'angelo").ToString();&lt;/CODE&gt;
&lt;BR&gt;&lt;I&gt;Results in the string &lt;CODE&gt;"Empl_Id=13 OR (NOT (Empl_Id=10) AND Empl_Name='D''angelo')"&lt;/CODE&gt;.&lt;/I&gt;
&lt;/OL&gt;
&lt;H2&gt;Todo&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;Support for &lt; and &gt; operators
&lt;LI&gt;Support for IN clause
&lt;LI&gt;Support for Datetime datatype
&lt;LI&gt;Support for Guid datatype
&lt;LI&gt;Support for SqlTypes datatypes
&lt;/UL&gt;
&lt;PRE&gt;
using System;

namespace NatMus.Data.Core {
  public class Filter {
    protected string sOperandName = "";
    protected string sSqlOperator = "";
    protected string sSqlPrefix = "";
    protected string sSqlPostfix = "";
    protected string sValue = "";
    protected bool bNegated = false;
    protected Filter oFilterLeft = null;
    protected Filter oFilterRight = null;

    public Filter() {
    }

    public Filter(string sOperandName) {
      this.sOperandName = sOperandName;
    }

    public Filter(Filter oFilter) {
      this.sOperandName = oFilter.sOperandName;
      this.sSqlOperator = oFilter.sSqlOperator;
      this.sValue = oFilter.sValue;
      this.bNegated = oFilter.bNegated;
      this.sSqlPrefix = oFilter.sSqlPrefix;
      this.sSqlPostfix = oFilter.sSqlPostfix;
    }

    public static Filter operator &amp; (Filter oFilterLeft, Filter oFilterRight) {
      Filter oFilterResult = new Filter();
      oFilterResult.sSqlPrefix = "(";
      oFilterResult.sSqlOperator = " AND ";
      oFilterResult.sSqlPostfix = ")";
      oFilterResult.oFilterLeft = oFilterLeft;
      oFilterResult.oFilterRight = oFilterRight;
      return oFilterResult;
    }

    public static Filter operator | (Filter oFilterLeft, Filter oFilterRight) {
      Filter oFilterResult = new Filter();
      oFilterResult.sSqlOperator = " OR ";
      oFilterResult.oFilterLeft = oFilterLeft;
      oFilterResult.oFilterRight = oFilterRight;
      return oFilterResult;
    }

    public static bool operator true(Filter v) {
      return false;
    }

    public static bool operator false(Filter v) {
      return false;
    }

    public override string ToString() {
      System.Text.StringBuilder oStringBuilder = new System.Text.StringBuilder();
      oStringBuilder.Append(sSqlPrefix);
      if ((object)oFilterLeft!=null) {
        oStringBuilder.Append(oFilterLeft.ToString());
      }
      oStringBuilder.Append(sOperandName + sSqlOperator + sValue);
      if ((object)oFilterRight!=null) {
        oStringBuilder.Append(oFilterRight.ToString());
      }
      oStringBuilder.Append(sSqlPostfix);
      return oStringBuilder.ToString();
    }

    public class StringFilter : Filter {
      public StringFilter(string sOperandName) : base(sOperandName) {
      }

      public StringFilter(Filter v) : base(v) {
      }

      public static StringFilter operator == (StringFilter v, string sValue) {
        StringFilter oFilter = new StringFilter(v);
        oFilter.sSqlOperator = "=";
        oFilter.sValue = "'" + sValue.ToString().Replace("'", "''") + "'";
        return oFilter;
      }

      public static StringFilter operator != (StringFilter v, string sValue) {
        return !(v==sValue);
      }

      public static StringFilter operator ! (StringFilter v) {
        StringFilter oFilter = new StringFilter(v);
        oFilter.bNegated = !oFilter.bNegated;
        if (oFilter.bNegated) {
          oFilter.sSqlPrefix = "NOT (" + oFilter.sSqlPrefix;
          oFilter.sSqlPostfix += ")";
        }
        return oFilter;
      }

      public override bool Equals(object o) {
        if (o==null) return false;
        return this==(StringFilter)o;
      }

      public override int GetHashCode() {
        return sOperandName.GetHashCode();
      }
    }

    public class IntFilter : Filter {
      public IntFilter(string sOperandName) : base(sOperandName) {
      }

      public IntFilter(Filter v) : base(v) {
      }

      public static IntFilter operator == (IntFilter v, int iValue) {
        IntFilter oFilter = new IntFilter(v);
        oFilter.sSqlOperator = "=";
        oFilter.sValue = iValue.ToString();
        return oFilter;
      }

      public static IntFilter operator != (IntFilter v, int iValue) {
        return !(v==iValue);
      }

      public static IntFilter operator ! (IntFilter v) {
        IntFilter oFilter = new IntFilter(v);
        oFilter.bNegated = !oFilter.bNegated;
        if (oFilter.bNegated) {
          oFilter.sSqlPrefix = "NOT (" + oFilter.sSqlPrefix;
          oFilter.sSqlPostfix += ")";
        }
        return oFilter;
      }

      public override bool Equals(object o) {
        if (o==null) return false;
        return this==(IntFilter)o;
      }

      public override int GetHashCode() {
        return sOperandName.GetHashCode();
      }
    }
  }
}
&lt;/PRE&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-111873981008105882?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/111873981008105882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=111873981008105882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/111873981008105882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/111873981008105882'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/06/writing-typesafe-sql-where-clauses.html' title='Writing typesafe SQL-WHERE clauses'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13566637.post-111865707189972796</id><published>2005-06-13T02:59:00.000-07:00</published><updated>2005-06-14T05:28:17.020-07:00</updated><title type='text'>Checking If Form Data Is Stale Before Saving</title><content type='html'>&lt;div&gt;
With multiple users working on the same database using ASP.NET webforms, you have to make a design decision how to prevent stale data from being saved. By definition in a web application the data you see in a form is a snapshot in time, so when you post your changes back to the server, the save method must check to see if the data you worked on is stale, meaning it has been changed by another user in the meantime. 
&lt;/div&gt;
&lt;pre&gt;
public void Form_OnSave() {
  if (DataIsStale()) {
    if (!WarnContinue("The data is stale, mate!"))
      return;
    }
  SaveData()
}&lt;/pre&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;DataIsStale&lt;/strong&gt;():&lt;/p&gt;&lt;blockquote&gt;&lt;strong&gt;MEANING&lt;/strong&gt;: The currently shown data has a RevisionNumber that is older than the data currently in database&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;strong&gt;RevisionNumber&lt;/strong&gt;:&lt;/blockquote&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;MEANING&lt;/strong&gt;: The RevisionNumber is the id of the last HistoryItem of an
"updated"-class type (created, changed, deleted, deactivated)&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;HistoryItem&lt;/strong&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;MEANING&lt;/strong&gt;: A record in a table called History with columns: history item id, date, user id, guid of element, historytype (created, viewed, changed,
deactivated, deleted, etc), session id (only in Method B)&lt;/p&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;Method A&lt;/span&gt;&lt;/p&gt;&lt;p&gt;When saving an element the RevisionNumbers are compared
&lt;BR&gt;&lt;strong&gt;UPSIDE&lt;/strong&gt;: Simple and easy solution
&lt;BR&gt;&lt;strong&gt;DOWNSIDE&lt;/strong&gt;: You need to store the revision number in the form&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;Method B&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The current SessionID is saved alongside the HistoryItem, so the date of the last HistoryItem of the viewed type and for the current SessionID is compared to the date of the last HistoryItem of an "updated"-class type for all other session ids.
&lt;BR&gt;&lt;strong&gt;UPSIDE&lt;/strong&gt;: Doesn't require any extra fields added to the form
&lt;BR&gt;&lt;strong&gt;DOWNSIDE&lt;/strong&gt;: The session id is the same when a user has more windows open so it will not alarm a user that edits the same element in two browser windows and saves them both.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;Method C&lt;/span&gt;&lt;/p&gt;&lt;p&gt;All the original data is compared to the current data in database, if different the the two objects must be different revisions, hence data is stale.&lt;BR&gt;
&lt;strong&gt;UPSIDE&lt;/strong&gt;: You don't need HistoryItems and RevisionNumbers and SessionIDs&lt;BR&gt;
&lt;strong&gt;DOWNSIDE&lt;/strong&gt;: All the orignal values must also be stored in the form&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13566637-111865707189972796?l=csharpedge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://csharpedge.blogspot.com/feeds/111865707189972796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13566637&amp;postID=111865707189972796' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/111865707189972796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13566637/posts/default/111865707189972796'/><link rel='alternate' type='text/html' href='http://csharpedge.blogspot.com/2005/06/checking-if-form-data-is-stale-before.html' title='Checking If Form Data Is Stale Before Saving'/><author><name>Troels Wittrup</name><uri>http://www.blogger.com/profile/15438685558423299625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://2.bp.blogspot.com/_uiZWeuk6kmE/SV6XH8bmDTI/AAAAAAAAACA/ND5c6sDo3CA/S220/bcc.jpg'/></author><thr:total>0</thr:total></entry></feed>
