<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.magenic.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Outsourcing to Sleestak</title><link>http://blog.magenic.com/blogs/jamesa/default.aspx</link><description>Technical Blog on ASP.NET AJAX, WCF, WPF, and any other shiny tinsel that captures a developer's short attention span, with hands on information about getting the most productivity out of your sleestak workforce.</description><dc:language>en</dc:language><generator>CommunityServer 2.1 (Build: 60809.935)</generator><item><title>The problem with computer literacy</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/10/06/The-problem-with-computer-literacy.aspx</link><pubDate>Mon, 06 Oct 2008 18:08:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:6504</guid><dc:creator>jamesa</dc:creator><slash:comments>8</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/6504.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=6504</wfw:commentRss><description>&lt;p&gt;A recent post on &lt;a href="http://www.boingboing.net/" target="_blank"&gt;Boing Boing&lt;/a&gt; is titled &lt;a href="http://www.boingboing.net/2008/10/06/paper-and-pencil-bet.html" target="_blank"&gt;Paper and pencil better for the brain than software&lt;/a&gt;?&amp;nbsp; The gist of the article and its associated links is that software, in guiding us through common tasks, actually makes us dumber.&amp;nbsp; The Dutch psychologist Christof van Nimwegen has performed studies demonstrating the deleterious effects of being plugged-in.&amp;nbsp; From the post:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;Van Nimwegen says much software turns us into passive beings, subjected to the whims of computers, randomly clicking on icons and menu options. In the long run, this hinders our creativity and memory, he says.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This certainly sounds right to me, from personal experience.&amp;nbsp; About a year ago, my company gave away GPS navigation devices as Christmas gifts to all the consultants.&amp;nbsp; The results are twofold.&amp;nbsp; On the one hand, we all make our appointments on time now, because we don&amp;#39;t get lost anymore.&amp;nbsp; On the other, we have all lost our innate sense of direction -- that essential skill that got the species through the hunter-gatherer phase of our development.&amp;nbsp; Without my GPS, I am effectively as blind as a bat without echolocation.&lt;/p&gt;&lt;p&gt;In Charles Stross&amp;#39;s novel about the near future, &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0441014151/charlieswebsi-20" target="_blank"&gt;Accelerando&lt;/a&gt;, this experience is taken a step further.&amp;nbsp; The protagonist Manfred Macx is at one point mugged on the street, and his connection to the Internet, which he carries around with him hooked up to his glasses, is taken away.&amp;nbsp; As a man of the pre-singularity, however, his personality has become so distributed over search engines and data portals that without this connection he is no longer able to even identify himself.&amp;nbsp; This is the nightmare of the technologically dependent.&lt;/p&gt;&lt;p&gt;Doctor van Nimwegen&amp;#39;s study recalls Plato&amp;#39;s ambivalence about the art of writing.&amp;nbsp; His mentor Socrates, it may be remembered, never put anything to writing, which he found inherently untrustworthy. Consequently all we know of Socrates comes by way of his disciple Plato.&amp;nbsp; Plato, in turn, was a poet who ultimately became distrustful of his own skills, and railed against it in his philosophical writings.&amp;nbsp; From the modern viewpoint, however, whatever it is that we lose when we put &amp;quot;living&amp;quot; thoughts down to writing, surely it is only through poetry that we are able to recover and sustain it.&lt;/p&gt;&lt;p&gt;It is through poetic imagery that Plato explains Socrates&amp;#39;s misgivings about letters in the &lt;a href="http://www9.georgetown.edu/faculty/jod/texts/phaedrus.html" target="_blank"&gt;Phaedrus&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;At the Egyptian city of Naucratis, there was a famous old god, whose name was Theuth; the bird which is called the Ibis is sacred to him, and he was the inventor of many arts, such as arithmetic and calculation and geometry and astronomy and draughts and dice, but his great discovery was the use of letters. Now in those days the god Thamus was the king of the whole country of Egypt; and he dwelt in that great city of Upper Egypt which the Hellenes call Egyptian Thebes, and the god himself is called by them Ammon. To him came Theuth and showed his inventions, desiring that the other Egyptians might be allowed to have the benefit of them; he enumerated them, and Thamus enquired about their several uses, and praised some of them and censured others, as he approved or disapproved of them. It would take a long time to repeat all that Thamus said to Theuth in praise or blame of the various arts. But when they came to letters, This, said Theuth, will make the Egyptians wiser and give them better memories; it is a specific both for the memory and for the wit. Thamus replied: O most ingenious Theuth, the parent or inventor of an art is not always the best judge of the utility or inutility of his own inventions to the users of them. And in this instance, you who are the father of letters, from a paternal love of your own children have been led to attribute to them a quality which they cannot have; for this discovery of yours will create forgetfulness in the learners&amp;#39; souls, because they will not use their memories; they will trust to the external written characters and not remember of themselves. &lt;strong&gt;The specific which you have discovered is an aid not to memory, but to reminiscence, and you give your disciples not truth, but only the semblance of truth; they will be hearers of many things and will have learned nothing; they will appear to be omniscient and will generally know nothing&lt;/strong&gt;; &lt;strong&gt;they will be tiresome company, having the show of wisdom without the reality.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;We can certainly see aspects of Manfred Macx&amp;#39;s experience of disorientation in our dependence on tools like Google and Wikipedia, which provide us all with the same degree of wisdom, or at least the same show of wisdom.&amp;nbsp; In tracking down the above quote about Theuth, I had to rely on a vague reminiscence that this memory passage occurred in either the Timaeus or the Phaedrus, and then used my browser search functionality to track down the specific paragraph.&amp;nbsp; Very handy, that search feature.&amp;nbsp; But how much more wonderful it would have been had I been able to call that up from my own theater of memory.&lt;/p&gt;&lt;p&gt;My only stand against the steady march of progress (from which I make my living, it should be remembered) is that I turn my spell-checker off when I write emails and articles.&amp;nbsp; A consulting manager recently chastised me for this practice, which he found error prone and somewhat irresponsible.&amp;nbsp; To this I could only reply, &amp;quot;but I already know how to spell.&amp;quot;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p&gt;I should have added, &amp;quot;...for now.&amp;quot;&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=6504" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Sleestak+Management/default.aspx">Sleestak Management</category></item><item><title>Visual Studio 2008 SP1 Toolbox Crash</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/10/04/Visual-Studio-2008-SP1-Toolbox-Crash.aspx</link><pubDate>Sat, 04 Oct 2008 17:18:27 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:6486</guid><dc:creator>jamesa</dc:creator><slash:comments>0</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/6486.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=6486</wfw:commentRss><description>&lt;p&gt;For the past month or so, whenever I tried to add a control to my Visual Studio Toolbox, the IDE would shut itself down.&amp;#160; My solution, of course, was to avoid adding tools to my Toolbox.&lt;/p&gt;  &lt;p&gt;Finally I decided that I needed to do something, ahem, a little smarter.&amp;#160; The specific problem occurred when I tried to use the Context Menu's &amp;quot;Choose Items...&amp;quot; option on my toolbox.&amp;#160;&amp;#160; It turns out that the &lt;a href="http://code.msdn.microsoft.com/PowerCommands" target="_blank"&gt;Power Commands&lt;/a&gt; (when did I install that?) has a conflict with VS 2008.&amp;#160; This apparently can also mess up the class viewer in Visual Studio 2008.&amp;#160; There are two work-arounds for this.&amp;#160;&amp;#160; The first is to hack a config file for your IDE settings.&amp;#160;&amp;#160; That solution can be found here: &lt;a title="http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/e2434065-9921-4861-b914-9cc9d6c55553/" href="http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/e2434065-9921-4861-b914-9cc9d6c55553/"&gt;http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/e2434065-9921-4861-b914-9cc9d6c55553/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Unfortunately this didn't work for me.&amp;#160; The second work-around is simply to uninstall the Power Commands.&amp;#160; If you go into Add/Remove Programs, it is listed as PowerCommands for Visual Studio 2008.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=6486" width="1" height="1"&gt;</description></item><item><title>Reflection</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/09/08/Reflection.aspx</link><pubDate>Mon, 08 Sep 2008 18:55:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:6058</guid><dc:creator>jamesa</dc:creator><slash:comments>0</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/6058.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=6058</wfw:commentRss><description>&lt;p&gt;Like may others, I recently received the fateful email notifying me that Lutz &lt;a href="http://blog.lutzroeder.com/" target="_blank"&gt;Roeder&lt;/a&gt; will be giving up his work on .NET Reflector, the brilliant and essential tool he developed to peer into the internal implementation of .NET assemblies.&amp;nbsp; Of course the whole idea of reflecting into an assembly is cheating a bit, since one of the principles of OO design is that we don&amp;#39;t care about implementations, only about contracts.&amp;nbsp; It gets worse, since one of the main reasons for using .NET Reflector is to reverse engineer someone else&amp;#39;s (particularly Microsoft&amp;#39;s) code.&amp;nbsp; Yet it is the perfect tool when one is good at reading code and simply needs to know how to do something special -- something that cannot be explained, but must be seen.&lt;/p&gt;&lt;p&gt;While many terms in computer science are drawn from other scientific fields, &lt;em&gt;reflection&lt;/em&gt; appears not to be.&amp;nbsp; Instead, it is derived from the philosophical &amp;quot;reflective&amp;quot; tradition, and is a synonym for looking inward: &lt;em&gt;introspection&lt;/em&gt;.&amp;nbsp; Reflection and introspection are not exactly the same thing, however.&amp;nbsp; This is a bit of subjective interpretation, of course, but it seems to me that unlike introspection, which is merely a turning inward, reflection tends to involve a stepping outside of oneself and peering at oneself.&amp;nbsp; In reflection, there is a moment of stopping and stepping back; the &amp;quot;I&amp;quot; who looks back on oneself is a cold and appraising self, cool and objective as a mirror.&lt;/p&gt;&lt;p&gt;Metaphors pass oddly between the world of philosophy and the world of computer science, often giving rise to peculiar reversals.&amp;nbsp; When concepts such as memory and CPU&amp;#39;s were being developed, the developers of these concepts drew their metaphors from the workings of the human mind.&amp;nbsp; The persistent storage of a computer is like the human faculty of memory, and so it was called &amp;quot;memory&amp;quot;.&amp;nbsp; The CPU works like the processing of the mind, and so we called it the central processing unit, sitting in the shell of the computer like a homunculus viewing a theater across which data is streamed.&amp;nbsp; Originally it was the mind that was the given, while the computer was modeled upon it.&amp;nbsp; Within a generation, the flow of metaphors has been reversed, and it is not uncommon find arguments about the computational nature of the brain based on analogies with the workings of computers.&amp;nbsp; Isn&amp;#39;t it odd that we remember things, just like computers remember things?&lt;/p&gt;&lt;p&gt;The ancient Skeptics had the concept of &lt;em&gt;epoche&lt;/em&gt; to describe this peculiar attitude of stepping back from the world, but it wasn&amp;#39;t until Descartes that this philosophical notion became associated with the metaphor of optics.&amp;nbsp; In a letter to Arnauld from 1648, Descartes writes:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;We make a distinction between direct and reflective thoughts corresponding to the distinction we make between direct and reflective vision, one depending on the first impact of the rays and the other on the second.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This form of reflective thought, in turn, also turns up in at an essential turning point in Descartes&amp;#39; discussion of his Method, when he realizes that his moment of self-awareness is logically dependent on something higher:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;In the next place, from reflecting on the circumstance that I doubted, and that consequently my being was not wholly perfect, (for I clearly saw that it was a greater perfection to know than to doubt,) I was led to inquire whence I had learned to think of something more perfect than myself;&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Descartes uses the metaphor in several places in the &lt;em&gt;Discourse on Method&lt;/em&gt;.&amp;nbsp; In each case, it is as if, after doing something, for instance doubting, he is looking out the corner of his eye at a mirror to see what he looks like when he is doing it, like an angler trying to perfect his cast or an orator attempting to improve his hand gestures.&amp;nbsp; In each case, what one sees is not quite what one expects to see; what one does is not quite what one thought one was doing.&amp;nbsp; The act of reflection provides a different view of ourselves from what we might observe from introspection alone.&amp;nbsp; For Descartes, it is always a matter of finding out what one is &amp;quot;really&amp;quot; doing, rather than what one thinks one is doing.&lt;/p&gt;&lt;p&gt;This notion of philosophical &amp;quot;true sight&amp;quot; through reflection is carried forward, on the other side of the channel, by Locke.&amp;nbsp; In his &lt;em&gt;Essay Concerning Human Understanding&lt;/em&gt;, Locke writes:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;This source of ideas every man has wholly in himself; and though it be not sense, as having nothing to do with external objects, yet it is very like it, and might properly enough be called &lt;em&gt;internal sense&lt;/em&gt;. But as I call the other Sensation, so I call this REFLECTION, the ideas it affords being such only as the mind gets by reflecting on its own operations within itself. By reflection then, in the following part of this discourse, I would be understood to mean, that notice which the mind takes of its own operations, and the manner of them, by reason whereof there come to be ideas of these operations in the understanding.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Within a century, &lt;em&gt;reflection&lt;/em&gt; becomes so ingrained in philosophical thought, if not identified with it, that Kant is able to talk of &amp;quot;transcendental reflection&amp;quot;: &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;Reflection (reflexio) is not occupied about objects themselves, for the purpose of directly obtaining conceptions of them, but is that state of the mind in which we set ourselves to discover the subjective conditions under which we obtain conceptions.&lt;/p&gt;&lt;p&gt;...&lt;/p&gt;&lt;p&gt;&amp;quot;The act whereby I compare my representations with the faculty of cognition which originates them, and whereby I distinguish whether they are compared with each other as belonging to the pure understanding or to sensuous intuition, I term transcendental reflection.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In the 20th century, the reflective tradition takes a peculiar turn.&amp;nbsp; While the phenomenologists continued to use it as the central engine of their philosophizing, Wilfred Sellars began his attack on &amp;quot;the myth of the given&amp;quot; upon which phenomenological reflection depended.&amp;nbsp; From an epistemological viewpoint, Sellars questions the implicit assumption that we, as thinking individuals, have any privileged access to our own mental states. Instead, Sellars posits that what we actually have is not clear vision of our internal mental states, but rather a culturally mediated &amp;quot;folk psychology&amp;quot; of mind that we use to describe those mental states.&amp;nbsp; In one fell swoop, Sellars sweeps away the Cartesian tradition of self-understanding that informs the &lt;em&gt;cogito ergo sum&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;In a sense, however, this isn&amp;#39;t truly a reversal of the reflective tradition but merely a refinement.&amp;nbsp; Sellars and his contemporary heirs, such as the Churchlands and Daniel Dennett, certainly provided a devastating blow to the reliability of philosophical introspection.&amp;nbsp; The Cartesian project, however, was not one of introspection, nor is the later phenomenological project.&amp;nbsp; The &amp;quot;given&amp;quot; was always assumed to be unreliable in some way, which is why philosophical &amp;quot;reflection&amp;quot; is required to analyze and correct the &amp;quot;given.&amp;quot;&amp;nbsp; All that Sellars does is to move the venue of philosophical reflection from the armchair to the laboratory, where it no doubt belongs.&lt;/p&gt;&lt;p&gt;A more fundamental attack on the reflective tradition came from Italy approximately 200 hundred years before Sellars.&amp;nbsp; Giambattista Vico saw the danger of the Cartesian tradition of philosophical reflection as lying in its undermining of the given of cultural institutions.&amp;nbsp; A professor of oratory and law, Vico believed that common understanding held a society together, and that the dissolution of civilizations occurred not when those institutions no longer held, but rather when we begin to doubt that they even exist.&amp;nbsp; On the face of it, it sounds like the rather annoying contemporary arguments against &amp;quot;cultural relativism&amp;quot;, but is actually a bit different.&amp;nbsp; Vico&amp;#39;s argument is rather that we all live in a world of myths and metaphors that help us to regulate our lives, and in fact contribute to what makes us human, and able to communicate with one another.&amp;nbsp; In the 1730 edition of the &lt;u&gt;New Science&lt;/u&gt;, Vico writes:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;quot;Because, unlike in the time of the barbarism of sense, the barbarism of reflection pays attention only to the words and not to the spirit of the laws and regulations; even worse, whatever might have been claimed in these empty sounds of words is believed to be just.&amp;nbsp; In this way the barbarism of reflection claims to recognize and know the just, what the regulations and laws intend, and endeavors to defraud them through the superstition of words.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;For Vico, the reflective tradition breaks down those civil bonds by presenting man as a rational man who can navigate the world of social institutions as an individual, the solitary &lt;em&gt;cogito&lt;/em&gt; who sees clearly, and cooly, the world as it is.&lt;/p&gt;&lt;p&gt;This begets the natural question, does &lt;em&gt;reflection&lt;/em&gt; really provide us with true sight, or does it merely dissociate ourselves from our inner lives in such a way that we only see what we want to see?&amp;nbsp; In computer science of course (not that this should be any guide to philosophy) the latter is the case.&amp;nbsp; Reflection is accomplished by publishing metadata about a code library which may or may not be true.&amp;nbsp; It does not allow us to view the code as it really is, but rather provides us a mediated view of the code, which is then associated with the code.&amp;nbsp; We assume it is reliable, but there is no way of really knowing until something goes wrong.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=6058" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Sleestak+Management/default.aspx">Sleestak Management</category></item><item><title>AJAX Control Toolkit: Script Only</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/08/26/AJAX-Control-Toolkit_3A00_-Script-Only.aspx</link><pubDate>Tue, 26 Aug 2008 16:15:04 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:5819</guid><dc:creator>jamesa</dc:creator><slash:comments>0</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/5819.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=5819</wfw:commentRss><description>&lt;p&gt;I previously posted about how to use the Microsoft Ajax Library in order to provide Globalization script functionality without using the ScriptManager control.&amp;#160; Why would you want to do this?&lt;/p&gt;  &lt;p&gt;One issue is that Microsoft is currently working on the ASP.NET MVC framework, which will provide a way of doing web applications that is more familiar to PHP and JSP programmers.&amp;#160; In other words, it doesn't use the WebForms infrastructure that has underpinned Microsoft's whole approach to web development for the past six years.&amp;#160; The original promise of WebForms was to abstract web development so it looks more like traditional Windows Forms development.&amp;#160; In order to accomplish this, the developers at Microsoft have worked hard to abstract the underlying web technology using windows components that render html and emit client script for the developer.&lt;/p&gt;  &lt;p&gt;But now the tide is turning, and with WPF and XAML, Microsoft's newest technology for building desktop applications, we are seeing a transition to the development metaphors that we have become accustomed to in web development.&lt;/p&gt;  &lt;p&gt;ASP.NET AJAX was originally developed following the WebForms paradigm.&amp;#160; While other AJAX frameworks provided script libraries that you needed to manipulate using client script (typically javascript), Microsoft provided their framework wrapped in controls like the ScriptManager and the UpdatePanel.&amp;#160; Even the Ajax Control Toolkit, the Microsoft backed opensource project that extends ASP.NET AJAX with additional controls, follows this model.&lt;/p&gt;  &lt;p&gt;But the MVC model doesn't follow this model.&amp;#160; It follows the model followed by every other vendor of web technology.&lt;/p&gt;  &lt;p&gt;So how do ASP.NET MVC and ASP.NET AJAX come together if they follow these radically different models?&amp;#160; Well ... the Microsoft AJAX team also provides the underlying scripts for their framework in the &lt;a href="http://www.asp.net/ajax/downloads/library/default.aspx?wwwaspnetrdirset=1" target="_blank"&gt;Microsoft Ajax Library&lt;/a&gt;, which can be used in JSP, PHP, or even your traditional HTML page if you are willing to do the muscle work required to hook into them.&amp;#160; They can also, of course, be used with the MVC framework.&lt;/p&gt;  &lt;p&gt;The Ajax Control Toolkit now also exposes its underlying script files for general use, allowing use to get all the great ACT functionality with WebForms or a ScriptManager.&amp;#160; The only problem is that learning to use the library without controls to manage our state and emit our code is difficult, and there is very little online help to get you started.&lt;/p&gt;  &lt;p&gt;Stephen Walther is now helping people through this difficulty on his &lt;a href="http://weblogs.asp.net/stephenwalther/" target="_blank"&gt;blog&lt;/a&gt;, and it is a wonderful thing.&amp;#160; He has already tackled the &lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/08/22/asp-net-mvc-tip-36-create-a-popup-calendar-helper.aspx" target="_blank"&gt;Popup Calendar&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/08/23/asp-net-mvc-tip-37-create-an-auto-complete-text-field.aspx" target="_blank"&gt;Autocomplete&lt;/a&gt;.&amp;#160; Expect to hear more from him in the near future.&amp;#160; I can't wait to see what he does next.&lt;/p&gt;  &lt;p&gt;h/t to Bertrand Leroy's &lt;a href="http://weblogs.asp.net/bleroy/" target="_blank"&gt;Tales From the Evil Empire&lt;/a&gt; for highlighting this.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=5819" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Ajax/default.aspx">Ajax</category></item><item><title>Recipe: Session Expired Monitor with ASP.NET AJAX</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/08/25/Recipe_3A00_-Session-Expired-Monitor-with-ASP.NET-AJAX.aspx</link><pubDate>Mon, 25 Aug 2008 19:19:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:5808</guid><dc:creator>jamesa</dc:creator><slash:comments>2</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/5808.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=5808</wfw:commentRss><description>&lt;div id="container"&gt;&lt;div id="centrecontent"&gt;&lt;div class="dayItems"&gt;&lt;div class="items"&gt;&lt;div class="item"&gt;&lt;div class="itemContents"&gt;&lt;div class="itemBody"&gt;&lt;p&gt;&lt;a href="http://www.imaginativeuniversal.com/ct.ashx?id=b5fda1b7-c69a-4d0c-ba47-c8fb2a1f113b&amp;amp;url=http%3a%2f%2fwww.imaginativeuniversal.com%2fcodesamples%2fSessionTimeout.zip" target="_blank"&gt;code download&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sessions are a way of preserving information on a web site between page hits, allowing the programmer to emulate a stateful application when, in fact, web pages are not really stateful.&amp;nbsp; They are also among the banes of web development, since sessions eventually timeout when there is no interaction between the user and the web app for a prolonged period of time.&amp;nbsp; In ASP.NET, this period has a default of 20 minutes, which is really hardly enough time to pick up a donut, refill one&amp;#39;s coffee, and chat with fellow workers before returning to one&amp;#39;s computer.&amp;nbsp; What this often means is that the user, upon returning to their computer and continuing work after a 20 minute break will find that all of the data entry they have been doing has been lost.&amp;nbsp; Worse, strange errors will begin to appear in his web browser if the loss of a session is not handled gracefully.&amp;nbsp; &lt;/p&gt;&lt;p&gt;The most common workaround is to increase the session grace period, called the session timeout.&amp;nbsp; This is set in your web.config file, and typically looks like this (the timeout period is measured in minutes):&lt;/p&gt;&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sessionState&lt;/span&gt;
      &lt;span class="attr"&gt;mode&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;InProc&amp;quot;&lt;/span&gt;
      &lt;span class="attr"&gt;cookieless&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;
      &lt;span class="attr"&gt;timeout&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;20&amp;quot;&lt;/span&gt;
     &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;A second way of handling this is to add extra code to an app that keeps the session state alive even if the user isn&amp;#39;t doing anything.&lt;/p&gt;&lt;p&gt;A third, and the most common, way is to provide code that redirects a user to a &amp;quot;session expired&amp;quot; page if they try to interact with a web page for which the session has timed-out.&amp;nbsp; This can be a bit awkward, however, since it is a passive solution that can cause the user some dismay as they hit a submit key only to be taken to a completely unexpected page.&lt;/p&gt;&lt;p&gt;This post deals with an active approach to the same problem.&amp;nbsp; When the user&amp;#39;s session has expired, it will generate a popup message in the user&amp;#39;s browser window letting him know that he has been inactive for too long.&amp;nbsp; Additionally it can redirect the browser to a new page with a warning message letting him know what happened.&amp;nbsp; The user still loses all of his work, of course, but at least this way he knows what happened when he returns to his desk following his coffee break.&lt;/p&gt;&lt;p&gt;This solution uses three tricks.&amp;nbsp; One is the event model for Master Pages in ASP.NET:&amp;nbsp; whenever a Content Page is refreshed, its OnLoad event is called,&amp;nbsp; along with the OnLoad events of the Master Page and any user controls hosted by either the Content Page or the Master Page (the actual order of these events is 1. controls on the Master Page, 2. controls in the Content Page, 3. the Master Page and finally 4. the Content Page).&lt;/p&gt;&lt;p&gt;The second trick is the way ASP.NET Extensions Timer control gets reset.&amp;nbsp; This is done simply by setting the interval to a new value.&amp;nbsp; Every time the interval is set to a new value, or even the same value, the countdown on the timer begins again.&lt;/p&gt;&lt;p&gt;The third trick is that the session timeout one sets in the web.config file can be read programmatically simply by querying a property of the Session object.&lt;/p&gt;&lt;p&gt;Putting all of this together, one can build a web user control that simply sits on a Master Page and knows when the user session is ready to expire.&amp;nbsp; It resets itself to the full timeout period any time a Content Page is refreshed.&amp;nbsp; when the session expires, the user control can raise an informative message, redirect to another page, or, potentially, simply extend the session timeout (not covered here, but easy to do if you are interested).&lt;/p&gt;&lt;p&gt;A user control to monitor the session timeout is included in the code sample linked at the top of this post.&amp;nbsp; Here is how you can build your own.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h2&gt;Session Timeout Monitor Recipe:&lt;/h2&gt;&lt;p&gt;Ingredients:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;One Master Page &lt;/li&gt;&lt;li&gt;One User Control &lt;/li&gt;&lt;li&gt;An Update Panel &lt;/li&gt;&lt;li&gt;An ASP.NET Ajax Extensions Timer &lt;/li&gt;&lt;li&gt;A Panel control &lt;/li&gt;&lt;li&gt;A Button control&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1. Create a new User Control in your project.&amp;nbsp; &lt;/p&gt;&lt;p&gt;2. Drop an Update Panel on the User Control and set its mode property to &amp;quot;Always&amp;quot;.&lt;/p&gt;&lt;p&gt;3. Add an Extensions Timer (not to be confused with the Futures TimerControl) to your project, dropping it in the Update Panel.&amp;nbsp; Name it &lt;em&gt;TimerTimeout&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Normally, this configuration of the timer control and a conditional update panel is used to refresh a portion of a web page on a regular schedule, for instance in order to create a self-updating clock display.&amp;nbsp; In this case, however, the timer and update panel are used simply to trigger a notification that the session has expired. &lt;/p&gt;&lt;p&gt;4. In the User Control&amp;#39;s code behind, add the following lines to the OnLoad event:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
        {
            &lt;span class="kwrd"&gt;int&lt;/span&gt; milliseconds = 60000;
            TimerTimeout.Interval = Session.Timeout * milliseconds;
        }&lt;/pre&gt;&lt;p&gt;This event will be called any time a content page is refreshed.&amp;nbsp; Whenever this happens, the code inside the event handler resets the AJAX Extensions Timer control to the full session lifespan as set in the web config file, in effect making the timeout for the Timer match the timeout for the session.&lt;/p&gt;&lt;p&gt;Since the Timer control&amp;#39;s Interval property is measured in milliseconds, while the session.Timeout is measured in minutes, a conversion factor of sixty thousand must be used to translate one time period into the other.&lt;/p&gt;&lt;p&gt;To finish this notifier, the Timer&amp;#39;s Tick event needs to be handled.&amp;nbsp; The Tick event gets called when the Timer&amp;#39;s Interval finally runs out.&amp;nbsp; In this implementation, the Tick event can either generate a popup message or cause a page redirect.&lt;/p&gt;&lt;p&gt;5. Place a Panel inside the Update Panel.&amp;nbsp; Set its Visible property to false.&lt;/p&gt;&lt;p&gt;6. Write a simple message inside the Update Panel, such as &amp;quot;Your session has expired.&amp;quot;&lt;/p&gt;&lt;p&gt;7. Drop a Button inside the Panel.&amp;nbsp; This Button will be used to allow the user to hide the popup message.&lt;/p&gt;&lt;p&gt;8. Add a public property to the User Control called &lt;em&gt;SessionExpiredRedirect&lt;/em&gt;:&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _sessionExpiredRedirect;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; SessionExpiredRedirect
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _sessionExpiredRedirect; }
            set { _sessionExpiredRedirect = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
        }&lt;/pre&gt;&lt;p&gt;This will be used to set the web page to which the Timer will redirect the user upon session timeout.&amp;nbsp; If no value is set, a popup message will appear, instead.&lt;/p&gt;&lt;p&gt;9. Handle the Timer&amp;#39;s Tick event:&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TimerTimout_Tick(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
        {

            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(SessionExpiredRedirect))
            {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (SessionExpiredRedirect.IndexOf(&lt;span class="str"&gt;&amp;quot;~&amp;quot;&lt;/span&gt;)==0)
                    Response.Redirect(
                        VirtualPathUtility.ToAppRelative(
                        SessionExpiredRedirect));
                &lt;span class="kwrd"&gt;else&lt;/span&gt;
                    Response.Redirect(SessionExpiredRedirect);
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
                &lt;span class="kwrd"&gt;this&lt;/span&gt;.PanelTimeout.Visible = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }&lt;/pre&gt;&lt;p&gt;This handler checks to see if a value has been set for the SessionExpiredRedirect property.&amp;nbsp; If not, it makes the Panel control inside the Update Panel visible.&lt;/p&gt;&lt;p&gt;10. To make the Panel control truly popup, set its CssClass property to &amp;quot;timeoutMessage&amp;quot;.&amp;nbsp; Add the following css style to the page.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/css&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
.timoutMessage
{
    position:absolute;
    top:100px;
    left:200px;
    background-color:#F5F7F8;
    border-style:groove;
    border-color:Navy;
    padding:15px;
}
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;11. Finally, compile this User Control and drag it on to the Master Page.&amp;nbsp; In design mode, the user control will display a misleading exception message.&amp;nbsp; Just ignore it.&lt;/p&gt;&lt;p&gt;12. Make sure the Master Page includes an ASP.NET AJAX Script Manager component.&lt;/p&gt;&lt;p&gt;This completes the recipe.&amp;nbsp; Any Content Page in this project will now automatically include the timeout monitor you have built.&amp;nbsp; Cookies are optional: this recipe will work with a session managed either with cookies or in &lt;em&gt;cookieless&lt;/em&gt; mode.&amp;nbsp; It will only work if the session mode is &lt;em&gt;InProc&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Garnish with buttered radishes.&amp;nbsp; Serve at room temperature.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=5808" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Ajax/default.aspx">Ajax</category></item><item><title>Extending the Ajax Control Toolkit Tab Container with Lazy Loading</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/08/25/Extending-the-Ajax-Control-Toolkit-Tab-Container-with-Lazy-Loading.aspx</link><pubDate>Mon, 25 Aug 2008 15:06:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:5807</guid><dc:creator>jamesa</dc:creator><slash:comments>1</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/5807.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=5807</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://www.imaginativeuniversal.com/codesamples/imaginativeuniversalextenders.zip" target="_blank"&gt;download source code&lt;/a&gt;&lt;/p&gt;&lt;p&gt;ASP.NET has been missing a good, free tab control for a long time.&amp;nbsp; With the ACT Tab Container, we were finally given one.&amp;nbsp; It typically runs in client-side only mode, but can interact with server-code if we set its &lt;strong&gt;AutoPostback&lt;/strong&gt; property to true.&lt;/p&gt;&lt;p&gt;Compared to what we had before, it is a huge improvement.&amp;nbsp; The peculiar thing about it, however, is that it isn&amp;#39;t actually an Ajax control.&amp;nbsp; It doesn&amp;#39;t use asynchronous postbacks or web service calls to talk to the server -- instead you just have these two mode: run it using client script only, or run it using server-side events and code-behind only.&lt;/p&gt;&lt;p&gt;So a few months ago I rectified this for a project, and only found out afterwards that Matt Berseth had already outlined the technique on his &lt;a href="http://mattberseth.com/blog/2007/07/how_to_lazyload_tabpanels_with.html" target="_blank"&gt;blog&lt;/a&gt;.&amp;nbsp; You basically run the tab container in client-side mode, and add update panels to the tab panels that you want to be ajaxy.&amp;nbsp; You then hook up the client-side ActivePageChanged event in such a way that it spoofs the Update Panel contained in the tab, causing an asynchronous (or partial) postback.&lt;/p&gt;&lt;p&gt;Matt also gave this technique a cool name.&amp;nbsp; He called it &amp;#39;lazy loading the tab panel&amp;#39;.&amp;nbsp; Like lazy loading in OOP, using this technique the update panels inside each tab panel only do something when its tab is selected.&amp;nbsp; Information is loaded only when its needed, and not before.&lt;/p&gt;&lt;p&gt;I must admit that I hold some resentment against Matt for coming up with this first, and for coming up with the cool moniker for it.&amp;nbsp; On the other hand, the solution I came up with encapsulates all of the javascript needed for this into a nice simple extender control that you can drop on your page, which his does not, and I&amp;#39;m rather proud of this.&lt;/p&gt;&lt;p&gt;The VS 2008 project for this extender is linked at the top of this post.&amp;nbsp; To use it, you need to compile the project and add the compiled assembly to your project, or else just add the project to your solution and add a project reference.&lt;/p&gt;&lt;p&gt;1. Drop the TabContainerExtender control into your page.&lt;/p&gt;&lt;p&gt;2. Set the Extender&amp;#39;s &lt;strong&gt;TargetControlID&lt;/strong&gt; property to your TabContainer&amp;#39;s ID.&lt;/p&gt;&lt;p&gt;3. In the RegisterUpdatePanels element of the Extender, map your tabs to your update panels.&amp;nbsp; This mapping tells the extender which Update Panels to activate when each tab is selected.&lt;/p&gt;&lt;p&gt;Your markup will look something like this:&lt;/p&gt;&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:TabContainerExtender&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainerExtender1&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;TargetControlID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainer1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;OnActiveTabChanged&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ActiveTabChanged&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegisterUpdatePanels&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel1&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel2&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel3&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegisterUpdatePanels&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc2:TabContainerExtender&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;4. If you want to add some code-behind to your active tab changed event, add set the OnActiveTabChanged property of the Extender to the name of your handler.&amp;nbsp; The thrown event will pass the correct Index number for the active Tab, as well as the ID of the mapped Update Panel.&amp;nbsp; The handler&amp;#39;s signature looks like this:&lt;/p&gt;&lt;blockquote&gt;&lt;div style="font-family:courier new;background:#f5f5f5;color:black;font-size:10pt;border:#000000 1px groove;padding:4px;"&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ActiveTabChanged(&lt;span style="color:blue;"&gt;int&lt;/span&gt; index, &lt;span style="color:blue;"&gt;string&lt;/span&gt; panelID)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;I highly encourage you to read Matt Berseth&amp;#39;s blog entry (which I have to admit is pretty good) to get a clear idea of the techniques being applied in this ajax extender.&amp;nbsp; If you just need a quick solution, however, feel free to download this code from the link at the top and use it any way you like with no strings attached.&amp;nbsp; There is a sample project attached to the solution that will demonstrate how to use the Tab Container Extender, in case you run into any problems with lazy loading your panels.&lt;/p&gt;&lt;p&gt;For reference, here is the code for the sample implementation, which loads controls on the fly based on the tab selected:&lt;/p&gt;&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc1:TabContainer&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainer1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabPanel1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Tab Panel 1&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        Content 1 ...
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;PlaceHolder1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;      
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;    
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabPanel2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Tab Panel 2&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        Content 2 ...
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;PlaceHolder2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;      
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;    
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabPanel3&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Tab Panel 3&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel3&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        Content 3 ...
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;PlaceHolder3&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:PlaceHolder&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;      
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;    
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc1:TabPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc1:TabContainer&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:TabContainerExtender&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainerExtender1&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;TargetControlID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TabContainer1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;OnActiveTabChanged&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ActiveTabChanged&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegisterUpdatePanels&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel1&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel2&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;cc2:UpdatePanelInfo&lt;/span&gt; &lt;span class="attr"&gt;TabIndex&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;UpdatePanelID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel3&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegisterUpdatePanels&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;cc2:TabContainerExtender&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/blockquote&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=5807" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Ajax/default.aspx">Ajax</category></item><item><title>Ajax AutoComplete Extender with WCF</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/08/22/Ajax-AutoComplete-Extender-with-WCF.aspx</link><pubDate>Fri, 22 Aug 2008 14:41:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:5780</guid><dc:creator>jamesa</dc:creator><slash:comments>0</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/5780.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=5780</wfw:commentRss><description>&lt;p&gt;The problem with conjuring tricks is that they lose practically all their glamour once you find out how they are done.&amp;nbsp; It&amp;#39;s very cool to see David Blaine walk down the street, do a few passes over his hand, and resurrect a fly which proceeds to flee.&amp;nbsp; It&amp;#39;s rather disappointing to do a google search and discover that in order to prepare for this trick, the first requirement is that you freeze a fly.&lt;/p&gt;&lt;p&gt;My trick is to make an &lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/AutoComplete/AutoComplete.aspx" target="_blank"&gt;autocomplete&lt;/a&gt; extender from the Ajax Control Toolkit call a WCF service instead of an asmx service.&amp;nbsp; For this recipe, I assume that you are already familiar with the autocomplete extender, and that you are using Visual Studio 2008.&amp;nbsp; I warn you in advance -- my trick disappoints.&amp;nbsp; It is so trivially easy that, once the technique spreads, it is very unlikely to impress your colleagues at work, much less get you a date with a &lt;a href="http://search.live.com/images/results.aspx?q=david+copperfield+claudia+schiffer&amp;amp;form=QBIR" target="_blank"&gt;supermodel&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Start by creating a new web project called AutocompleteWCF.&amp;nbsp; Add a reference to the &lt;em&gt;AjaxControlToolkit.dll&lt;/em&gt;.&amp;nbsp; Open up the default aspx page that is generated with your project, and add the following code to:&lt;/p&gt;&lt;p&gt;&lt;span class="kwrd"&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;form1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ScriptManager1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:TextBox&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;myTextBox&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;autocomplete&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;off&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ajaxToolkit:AutoCompleteExtender&lt;/span&gt;
                &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; 
                &lt;span class="attr"&gt;BehaviorID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;AutoCompleteEx&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;autoComplete1&amp;quot;&lt;/span&gt; 
                &lt;span class="attr"&gt;TargetControlID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;myTextBox&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;ServicePath&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Autocomplete.svc&amp;quot;&lt;/span&gt; 
                &lt;span class="attr"&gt;ServiceMethod&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GetCompletionList&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;MinimumPrefixLength&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; 
                &lt;span class="attr"&gt;CompletionInterval&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1000&amp;quot;&lt;/span&gt;
                &lt;span class="attr"&gt;EnableCaching&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ajaxToolkit:AutoCompleteExtender&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This is the standard demo code that is shipped with the Ajax Control Toolkit Sample Website.&amp;nbsp; I&amp;#39;ve simplified it a bit by removing the animations.&amp;nbsp; The only significant change I&amp;#39;ve made is to change the ServicePath from &lt;em&gt;Autocomplete.asmx&lt;/em&gt; to &lt;em&gt;Autocomplete.svc&lt;/em&gt;, the latter being the extension for a WCF service.&lt;/p&gt;&lt;p&gt;The next step is to create our service and add a GetCompletionList operation to it.&amp;nbsp; The easiest way to do this is to go to Add | New Item and just select the &lt;em&gt;Ajax-enabled WCF Service&lt;/em&gt; item template, but this would be so easy that it is hardly worth doing.&lt;/p&gt;&lt;p&gt;Instead, create a new WCF Service using the &lt;em&gt;WCF Service &lt;/em&gt;Item Template and call it Autocomplete.svc.&amp;nbsp; Visual Studio will automatically generate a service interface for you.&amp;nbsp; Delete the interface.&amp;nbsp; We don&amp;#39;t need it.&amp;nbsp; (To be more specific, I don&amp;#39;t know how to get this to work with an interface, so I&amp;#39;m just going to ignore that it is possible.)&lt;/p&gt;&lt;p&gt;Again, I am going to rip off the ACT sample app and just borrow the code from their webservice and place it in our WCF service.&amp;nbsp; The WCF service class (&lt;em&gt;Autocomplete.svc.cs&lt;/em&gt;) will look like this:&lt;/p&gt;&lt;div style="font-family:courier new;background:#f5f5f5;color:black;font-size:10pt;border:#000000 1px groove;padding:4px;"&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;ServiceContract&lt;/span&gt;(Namespace = &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)]&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;AspNetCompatibilityRequirements&lt;/span&gt;(RequirementsMode = &lt;span style="color:#2b91af;"&gt;AspNetCompatibilityRequirementsMode&lt;/span&gt;.Allowed)]&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Autocomplete&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color:#2b91af;"&gt;OperationContract&lt;/span&gt;]&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt;[] GetCompletionList(&lt;span style="color:blue;"&gt;string&lt;/span&gt; prefixText, &lt;span style="color:blue;"&gt;int&lt;/span&gt; count)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (count == 0)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; count = 10;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (prefixText.Equals(&lt;span style="color:#a31515;"&gt;&amp;quot;xyz&amp;quot;&lt;/span&gt;))&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt;[0];&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Random&lt;/span&gt; random = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Random&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt; items = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt;(count);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;for&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; count; i++)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;char&lt;/span&gt; c1 = (&lt;span style="color:blue;"&gt;char&lt;/span&gt;)random.Next(65, 90);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;char&lt;/span&gt; c2 = (&lt;span style="color:blue;"&gt;char&lt;/span&gt;)random.Next(97, 122);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;char&lt;/span&gt; c3 = (&lt;span style="color:blue;"&gt;char&lt;/span&gt;)random.Next(97, 122);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; items.Add(prefixText + c1 + c2 + c3);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; items.ToArray();&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;p&gt;A few things worth noting:&lt;/p&gt;&lt;p&gt;1. Autocomplete does not implement the IAutocomplete Interface.&amp;nbsp; Even though this is generated automatically, with the WCF Service item template, you should remove it.&lt;/p&gt;&lt;p&gt;2. The service contract has a blank Namespace explicitly declared.&amp;nbsp; &lt;/p&gt;&lt;p&gt;3. The &lt;em&gt;ASPNetCompatibilityRequirements&lt;/em&gt; attribute must be added to our class.&lt;/p&gt;&lt;p&gt;This takes care of the code that calls the WCF service, as well as the service itself.&amp;nbsp; We now have rig up the web.config file.&amp;nbsp; If you&amp;#39;ve been working with WCF for any length of time, then you know that this is where the problems usually occur.&amp;nbsp; Fortunately, the configuration is fairly simple.&amp;nbsp; You need to set up an endpoint behavior for your service that enables web scripting (much the way asmx web services must be decorated with the &lt;em&gt;ScriptService&lt;/em&gt; attribute in order to be called from client-script).&amp;nbsp; You also will need to turn AspNetCompatibilityEanbled on for the hosting environment.&lt;/p&gt;&lt;div style="font-family:courier new;background:#f5f5f5;color:black;font-size:10pt;border:#000000 1px groove;padding:4px;"&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpointBehaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behavior&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AjaxBehavior&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;enableWebScript&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behavior&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpointBehaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;behaviors&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;serviceHostingEnvironment&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;aspNetCompatibilityEnabled&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;services&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;service&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AutocompleteWCF.Autocomplete&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;endpoint&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;address&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;behaviorConfiguration&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AjaxBehavior&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;binding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;webHttpBinding&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;contract&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;AutocompleteWCF.Autocomplete&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;service&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;services&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;And that is all you need to do make the AutoComplete Extender work with a WCF service instead of an asmx web service.&amp;nbsp; I told you it would be unimpressive.&lt;/p&gt;&lt;p&gt;Of course, using a WCF service for Ajax has all the limitations that using an asmx file for Ajax did.&amp;nbsp; First of all, you can&amp;#39;t call a service that is in a different domain than the page which hosts your client-code.&amp;nbsp; This is a security feature, to prevent malicious code from redirecting your harmless javascript to something nasty on the world wide web.&lt;/p&gt;&lt;p&gt;Second, you can&amp;#39;t call just any service from your client-side code.&amp;nbsp; The service must be explicitly marked as something that can be called from client code.&amp;nbsp; In asmx web services, we used ScriptService for this.&amp;nbsp; In WCF services, we similarly use EnableWebScript binding property. &lt;/p&gt;&lt;p&gt;Now I feel like I&amp;#39;ve wasted your time, so here&amp;#39;s a YouTube &lt;a href="http://www.youtube.com/watch?v=s7Wvk-CVN-Y" target="_blank"&gt;video&lt;/a&gt; of David Blaine to make up for it.&amp;nbsp; And remember, David Blaine is to Chris Angel what Daisy Duke was to Alexis Carrington.&amp;nbsp; It&amp;#39;s an existential thing, and at some point, you&amp;#39;ve just got to pick sides and stay put in a way that will determine who you are for the rest of your life.&lt;/p&gt;&lt;p&gt;Are you a David Blaine/Daisy Duke kind of person or are you a Chris Angel/Alexis Carrington sort?&amp;nbsp; Do some soul searching and please let me know what you learn about yourself.&lt;/p&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=5780" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Ajax/default.aspx">Ajax</category></item><item><title>ASP.NET AJAX: Script Globalization without the ScriptManager</title><link>http://blog.magenic.com/blogs/jamesa/archive/2008/08/22/ASP.NET-AJAX_3A00_-Script-Globalization-without-the-ScriptManager.aspx</link><pubDate>Fri, 22 Aug 2008 14:40:00 GMT</pubDate><guid isPermaLink="false">2a277c9f-7f25-4670-9bb2-55c6ffd86e07:5779</guid><dc:creator>jamesa</dc:creator><slash:comments>0</slash:comments><comments>http://blog.magenic.com/blogs/jamesa/comments/5779.aspx</comments><wfw:commentRss>http://blog.magenic.com/blogs/jamesa/commentrss.aspx?PostID=5779</wfw:commentRss><description>&lt;p&gt;I just spent about four hours trying to solve a problem I&amp;#39;ll probably never actually encounter in the wild.&amp;nbsp; Someone posted on the &lt;a href="http://forums.asp.net/" target="_blank"&gt;asp.net forums&lt;/a&gt; about script globalization using ASP.NET AJAX.&amp;nbsp; This can be set up pretty easily by simply using the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.aspx" target="_blank"&gt;ScriptManager&lt;/a&gt; control and setting its EnableScriptGlobalization property to true.&amp;nbsp; ScriptManager takes care of importing the necessary scripts and handling all the underlying code required to make things work.&lt;/p&gt;&lt;p&gt;What the seeker on the forums wanted to know, however, was whether this could be accomplished without the ScriptManager.&amp;nbsp; In theory, all the ASP.NET AJAX framework scripts can be &lt;a href="http://msdn.microsoft.com/en-us/asp.net/bb944808.aspx" target="_blank"&gt;downloaded&lt;/a&gt; and used in a non-platform dependent manner.&lt;/p&gt;&lt;p&gt;Certain software problems are ubiquitous, and people tend to fall over themselves blogging and posting about them until Microsoft or some other vendor eventually either fixes the problem and it goes away.&amp;nbsp; On the other hand, there are problems in the software bestiary that are so rare that working on them is the programming equivalent of doing cryptozoology.&lt;/p&gt;&lt;p&gt;This was a juicy problem of that sort.&amp;nbsp; And I believe I have a solution. It basically involves redoing some of what the ScriptManager does automatically, but what the hey.&lt;/p&gt;&lt;p&gt;To support globalization in ecmascript, the ScriptManager basically sets a variable called __cultureInfo behind the scenes.&amp;nbsp; This is then used by various ASP.NET AJAX script methods to provide formatting information.&amp;nbsp; This is actually explained in the Microsoft &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc135974.aspx" target="_blank"&gt;documentation&lt;/a&gt; for the feature.&lt;/p&gt;&lt;p&gt;Behind the scenes, it seems clear, the ScriptManager is querying the &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.thread.currentuiculture.aspx" target="_blank"&gt;CurrentUICulture&lt;/a&gt; of the current thread in order to determine the browser&amp;#39;s preferred language, and passing this to the __cultureInfo variable.&amp;nbsp; The trick, then, is to determine the format of the culture data passed to __cultureInfo.&lt;/p&gt;&lt;p&gt;Here I had to use reflection to discover that there is an internal ClientCultureInfo type in the Sys.Web.Extensions assembly.&amp;nbsp; It made sense that this was being serialized and passed to the __cultureInfo variable.&amp;nbsp; With some trial and error, I finally got the serialization correct.&lt;/p&gt;&lt;p&gt;To make this work, you will need to download the Ajax Framework Library, which is a collection of javascript files.&amp;nbsp; You will need to import the MicrosoftAjax.js file into your web project, and then reference it in your page, like this:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;lt;script src=&amp;quot;MicrosoftAjax.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;You will also need to create the ClientCultureInfo class for your project, and make sure that it is serializable.&amp;nbsp; I tried DataContractJsonSerializer class to do my serializing,&amp;nbsp; but had problem getting the DateTimeFormatInfo type to serialize correctly, so I finally opted to use the now obsolete JavaScriptSerializer.&amp;nbsp; Here&amp;#39;s what the class looks like:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="font-family:courier new;background:#f5f5f5;color:black;font-size:10pt;border:#000000 1px groove;padding:4px;"&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ClientCultureInfo&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; name;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;DateTimeFormatInfo&lt;/span&gt; dateTimeFormat;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;NumberFormatInfo&lt;/span&gt; numberFormat;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; ClientCultureInfo(&lt;span style="color:#2b91af;"&gt;CultureInfo&lt;/span&gt; cultureInfo)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.name = cultureInfo.Name;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.numberFormat = cultureInfo.NumberFormat;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.dateTimeFormat = cultureInfo.DateTimeFormat;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; SerializedCulture(&lt;span style="color:#2b91af;"&gt;ClientCultureInfo&lt;/span&gt; info)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;JavaScriptSerializer&lt;/span&gt; js = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;JavaScriptSerializer&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; js.Serialize(info);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Now that we have the culture info formatted correctly, we need to be able to pass it to the client variable.&amp;nbsp; We&amp;#39;ll create a public property in the code-behind that is accessible from the client, and set its value in the Page.Load event handler:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="font-family:courier new;background:#f5f5f5;color:black;font-size:10pt;border:#000000 1px groove;padding:4px;"&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;protected&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt; e)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (!Page.IsPostBack)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;CultureInfo&lt;/span&gt; cultureInfo = System.Threading.&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.CurrentThread.CurrentUICulture;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;ClientCultureInfo&lt;/span&gt; o = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ClientCultureInfo&lt;/span&gt;(cultureInfo);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SerializedCulture = &lt;span style="color:#2b91af;"&gt;ClientCultureInfo&lt;/span&gt;.SerializedCulture(o);&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; SerializedCulture&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;set&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ViewState[&lt;span style="color:#a31515;"&gt;&amp;quot;kultur&amp;quot;&lt;/span&gt;] = &lt;span style="color:blue;"&gt;value&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;get&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (ViewState[&lt;span style="color:#a31515;"&gt;&amp;quot;kultur&amp;quot;&lt;/span&gt;] == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Empty;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; ViewState[&lt;span style="color:#a31515;"&gt;&amp;quot;kultur&amp;quot;&lt;/span&gt;].ToString();&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Finally, we&amp;nbsp; need to use this code-behind property to set __cultureInfo.&amp;nbsp; Just add the following script block to your markup in order to set the current culture:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;// Get the name field of the CurrentCulture object   &lt;/span&gt;
    &lt;span class="kwrd"&gt;var&lt;/span&gt; __cultureInfo = &lt;span class="str"&gt;&amp;#39;&amp;lt;%= this.SerializedCulture %&amp;gt;&amp;#39;&lt;/span&gt;;
    Sys.CultureInfo.CurrentCulture = Sys.CultureInfo._parse(__cultureInfo);
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;I added this to the bottom of the page.&amp;nbsp; To test whether this works, you will need to set the language property of your browser (if you are using IE, like I am).&amp;nbsp; I set mine to French for testing.&amp;nbsp; Then append the following script block below the one setting the culture above:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;var&lt;/span&gt; currentCultureInfoObj = Sys.CultureInfo.CurrentCulture;
    &lt;span class="kwrd"&gt;var&lt;/span&gt; d = &lt;span class="kwrd"&gt;new&lt;/span&gt; Date();
    alert(&lt;span class="str"&gt;&amp;quot;Current culture is &amp;quot;&lt;/span&gt; + currentCultureInfoObj.name 
    + &lt;span class="str"&gt;&amp;quot; and today is &amp;quot;&lt;/span&gt; 
    + d.localeFormat(&lt;span class="str"&gt;&amp;#39;dddd, dd MMMM yyyy HH:mm:ss&amp;#39;&lt;/span&gt;));  
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;p&gt;If you encounter any problems, it is possible that the web.config file is overriding the culture information from the browser.&amp;nbsp; In that case, make sure the culture is set to &amp;quot;auto&amp;quot; in the config file, like this:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="font-family:courier new;background:#f5f5f5;color:black;font-size:10pt;border:#000000 1px groove;padding:4px;"&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.web&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;globalization&lt;/span&gt;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;uiCulture&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;auto&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;culture&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;auto&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;system.web&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blog.magenic.com/aggbug.aspx?PostID=5779" width="1" height="1"&gt;</description><category domain="http://blog.magenic.com/blogs/jamesa/archive/tags/Ajax/default.aspx">Ajax</category></item></channel></rss>