<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>See Joel Program</title>
	<atom:link href="https://seejoelprogram.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://seejoelprogram.wordpress.com</link>
	<description>Life's More Interesting When You Know How It Works.</description>
	<lastBuildDate>Thu, 04 Jun 2009 03:50:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='seejoelprogram.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>https://s0.wp.com/i/buttonw-com.png</url>
		<title>See Joel Program</title>
		<link>https://seejoelprogram.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="https://seejoelprogram.wordpress.com/osd.xml" title="See Joel Program" />
	<atom:link rel='hub' href='https://seejoelprogram.wordpress.com/?pushpress=hub'/>
	<item>
		<title>Tell Me Everything You Know&#8230;</title>
		<link>https://seejoelprogram.wordpress.com/2009/06/01/tell-me-everything-you-know/</link>
					<comments>https://seejoelprogram.wordpress.com/2009/06/01/tell-me-everything-you-know/#comments</comments>
		
		<dc:creator><![CDATA[Joel Rumerman]]></dc:creator>
		<pubDate>Tue, 02 Jun 2009 03:05:18 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Interview]]></category>
		<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">http://seejoelprogram.wordpress.com/?p=192</guid>

					<description><![CDATA[Recently at work I got asked a couple questions at work about some hiring techniques that we might be implementing. I guess my company is defining and implementing a new hiring practice around the idioms presented in Who: The A Method for Hiring and they wanted my input on a couple of the steps they [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Recently at work I got asked a couple questions at work about some hiring techniques that we might be implementing. I guess my company is defining and implementing a new hiring practice around the idioms presented in <a href="http://www.amazon.com/Who-Method-Hiring-Geoff-Smart/dp/0345504194/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1243826594&amp;sr=1-1" target="_blank">Who: The A Method for Hiring</a> and they wanted my input on a couple of the steps they were batting around. I can’t say I’m for or against such an intensive, well defined hiring pattern yet, because it hasn’t been used yet and I haven’t really been that involved, but it did spark my interest in how I would hire a new developer today if given the chance.</p>
<p>What popped into my head is the “Tell Me Everything You Know…” methodology. My goal when I would interview somebody is to, in the shortest amount of time, figure out everything this person knows about technical things that indicate if the person is a standout developer or not.</p>
<p>Here’s the basic interview structure:</p>
<p>I’d tell them we were going to have a series of 5 minute conversations and in those 5 minute conversations they were supposed to tell me everything they know about whatever I asked them. Rather than taking notes, the conversation is recorded because this is going to happen way too fast for me to write anything down. Plus, I’ve found out over the years that notes I’ve written about most things are incomplete and tend to stall conversations.</p>
<p>What I’m going to be able to tell during this conversation is if they can communicate effectively, context switch quickly, respond to a bit of pressure, and if they have the technological chops I’m looking for. I’d say that the last one is the most important, but in my company if you can’t write a good email or switch your focus quickly, you’re kind of useless. This is the extend of how I would hire a developer. It sounds simplistic, but in my head it works.</p>
<p>Here’s my list of topics that I’d ask about. Everyone’s will be different, but these are ones that are important to me.</p>
<p>Tell Me Everything You Know About …</p>
<div style="float:left;">
<ul>
<li>Websites
<ul>
<li>HTTP</li>
<li>HTML</li>
<li>Standards</li>
<li>CSS</li>
<li>DIV vs. Table Layout</li>
<li>JavaScript</li>
<li>AJAX</li>
<li>JSON</li>
<li>Content Delivery Networks (CDN)</li>
<li>Verbs: POST, PUT, GET, etc.
<ul>
<li>SEO</li>
</ul>
</li>
<li>Sessions</li>
<li>Page Design</li>
</ul>
</li>
<li>Network Communication
<ul>
<li>TCP</li>
<li>HTTP</li>
<li>Stateful vs. Stateless</li>
</ul>
</li>
<li>Portable Data Structures
<ul>
<li>XML</li>
<li>XSL/XSLT</li>
<li>JSON</li>
</ul>
</li>
</ul>
</div>
<div style="float:left;">
<ul>
<li>Object Oriented Programming
<ul>
<li>Interfaces</li>
<li>Classes</li>
<li>Polymorphism</li>
<li>Inheritance</li>
<li>Is-A vs. Has-A</li>
<li>Data Structures</li>
</ul>
</li>
<li>Development Patterns
<ul>
<li>Factory</li>
<li>Strategy</li>
<li>Observer</li>
<li>Command</li>
<li>Assembler</li>
<li>Facade / Adapter</li>
<li>Builder</li>
</ul>
</li>
<li>The .NET Framework
<ul>
<li>Major improvements between versions</li>
<li>ASP.NET</li>
<li>ASP.NET Control Lifecycle</li>
<li>ASP.NET AJAX</li>
<li>Debugging</li>
<li>Compilation</li>
<li>Runtime</li>
<li>IL</li>
<li>Garbage Collection (Disposal, Finalization)</li>
<li>WCF</li>
<li>Win Form</li>
<li>WPF</li>
<li>SilverLight</li>
<li>WF</li>
<li>Generics</li>
<li>Linq</li>
<li>Object Initializers</li>
<li>Delegation</li>
<li>Anonymous Types</li>
<li>Visual Studio</li>
</ul>
</li>
</ul>
</div>
<div style="float:left;">
<ul>
<li>Software Engineering Lifecycle
<ul>
<li>Discovery</li>
<li>Task Estimation</li>
<li>Requirements Gathering</li>
<li>Rapid Application Development</li>
<li>Iteration Development</li>
<li>Software Maintenance</li>
<li>Software Deployment</li>
<li>Short term vs. long term wins</li>
</ul>
</li>
<li>Databases
<ul>
<li>SQL</li>
<li>SQL Server Data Types</li>
<li>Indexes</li>
<li>Query Performance</li>
<li>Storage (trees)</li>
</ul>
</li>
<li>Storage Technologies
<ul>
<li>SANs</li>
<li>NAS</li>
</ul>
</li>
<li>Testing
<ul>
<li>Unit Tests</li>
<li>Black Box vs. White Box</li>
<li>Load</li>
<li>Requests / Second</li>
</ul>
</li>
<li>Cloud Computing</li>
</ul>
</div>
<div style="float:left;">
<ul>
<li>ProgrammingTools</li>
<ul>
<li>Visual Studio</li>
<li>Fiddler</li>
<li>Firebug</li>
<li>Web Developer Toolbar</li>
<li>Yslow</li>
<li>IE Developer Toolbar / IE8 Integrated</li>
</ul>
<li>Website Performance</li>
<ul>
<li>No. HTTP Requests</li>
<li>Compression</li>
<li>Images / Sprites</li>
<li>Tables</li>
<li>Content size</li>
<li>JavaScript Execution Engines</li>
<li>CDN</li>
</ul>
</ul>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://seejoelprogram.wordpress.com/2009/06/01/tell-me-everything-you-know/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/b36ab77f5bbc03913a2a397c3960b1762bd883326274bdbee69e06549aaca06c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jrumerman</media:title>
		</media:content>
	</item>
		<item>
		<title>Maintaining ASP.NET Session State in an Ajax Application</title>
		<link>https://seejoelprogram.wordpress.com/2008/11/10/maintaining-aspnet-session-state-in-an-ajax-application/</link>
					<comments>https://seejoelprogram.wordpress.com/2008/11/10/maintaining-aspnet-session-state-in-an-ajax-application/#comments</comments>
		
		<dc:creator><![CDATA[Joel Rumerman]]></dc:creator>
		<pubDate>Tue, 11 Nov 2008 05:33:58 +0000</pubDate>
				<category><![CDATA[ASP.NET AJAX]]></category>
		<guid isPermaLink="false">http://seejoelprogram.wordpress.com/2008/11/10/maintaining-aspnet-session-state-in-an-ajax-application/</guid>

					<description><![CDATA[Recently, I&#8217;ve been working with applications that require very few postbacks. While this has been great from a usability perspective, after all the application is very ajaxy and responsive, it&#8217;s caused some unexpected problems. One problem that it caused is that ASP.NET Sessions were expiring even though the user was actively using the application. The [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Recently, I&#8217;ve been working with applications that require very few postbacks. While this has been great from a usability perspective, after all the application is very ajaxy and responsive, it&#8217;s caused some unexpected problems. One problem that it caused is that ASP.NET Sessions were expiring even though the user was actively using the application.</p>
<p>The Sessions were expiring because the user wasn&#8217;t causing a postback (full or partial) and thus executing the ASP.NET page life cycle, which takes care of maintaining Session for us by implementing the IRequireSessionState interface.</p>
<p>One way I could have solved this problem is to rehydrate Session whenever an Ajax request was received (such as by marking the web method as requiring Session), but this is a bad programming practice for a few reasons. First, having Session attached to a request and response isn&#8217;t very RESTful and breaks at least a couple of design rules. Second, it&#8217;s a relatively expensive operation to pull Session from the session store, deserialize it into the Session object, use it, maybe modify it, and then serialize it back out to the Session store when the request is complete. As Session gets bigger, this operation gets more expensive and I really want the Ajax features of the application to fly. Finally, I might not own the REST endpoints that I&#8217;m using for my application&#8217;s functionality. In that case, I&#8217;m talking to a third party service (i.e. Amazon&#8217;s S3 service), and not communicating at all with my application, but I still need to keep Session alive. The user doesn&#8217;t know or care that I&#8217;m talking to Amazon. They just think they&#8217;re using my application.</p>
<p>What I really wanted to do was <em>sometimes</em> revalidate Session while the user interacted with the Ajaxy parts of the application without the user paying any perceivable performance penalty and not breaking too many rules of application design.</p>
<p><span id="more-178"></span>To do this, I created a mechanism to execute a fire and forget request to a custom Http Handler that takes care of revalidating Session for us.</p>
<p><strong><a href="https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=JoelRumerman&amp;ReleaseId=1780" target="_blank">[Download the code here]</a></strong></p>
<p>First, let&#8217;s cover the the custom Http Handler:</p>
<pre class="code"><span style="color:blue;">using </span>System.Web;
<span style="color:blue;">using </span>System.Web.SessionState;

<span style="color:blue;">public class </span><span style="color:#2b91af;">OutOfBandSessionValidator </span>: <span style="color:#2b91af;">IHttpHandler</span>, <span style="color:#2b91af;">IRequiresSessionState
</span>{
    <span style="color:blue;">public bool </span>IsReusable
    {
        <span style="color:blue;">get </span>{ <span style="color:blue;">return false</span>; }
    }

    <span style="color:blue;">public void </span>ProcessRequest(<span style="color:#2b91af;">HttpContext </span>context)
    { }
}</pre>
<p>As you can see, out OutOfBandSessionValidator does almost nothing. The only thing really worth noting is that it implements the IRequiresSessionState interface that tells ASP.NET that when a request comes in, this handler requires that Session be retrieved and deserialized, and when the request completes, it serializes the Session object and stores it back in the Session store. This is the mechanism that will allow us to keep Session alive.</p>
<p>We wire up out custom handler just like any other Http Handler in the web.config like so:</p>
<pre class="code"><span style="color:blue;">&lt;</span><span style="color:#a31515;">httpHandlers</span><span style="color:blue;">&gt;
</span><span style="color:blue;">...
</span><span style="color:blue;"><strong>    &lt;</strong></span><strong><span style="color:#a31515;">add </span><span style="color:red;">verb</span><span style="color:blue;">=</span>"<span style="color:blue;">GET,HEAD</span>" <span style="color:red;">path</span><span style="color:blue;">=</span>"<span style="color:blue;">OutOfBandSessionValidator.ashx</span>" <span style="color:red;">type</span><span style="color:blue;">=</span>"<span style="color:blue;">OutOfBandSessionValidator</span>"</strong><span style="color:blue;"><strong>/&gt;
...</strong></span></pre>
<pre class="code"><span style="color:blue;">&lt;/</span><span style="color:#a31515;">httpHandlers</span><span style="color:blue;">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>(This is IIS 6 style.)<br />
We can now access our custom handler like so: <a href="http://localhost:1544/OutOfBandSessionValidator.ashx">http://localhost:1544/OutOfBandSessionValidator.ashx</a></p>
<p>Now that we&#8217;ve got our handler wired up, we need to create a mechanism to call it. For performance purposes, we want to call the handler in a way that doesn&#8217;t affect our application&#8217;s performance (perceived or real) and we don&#8217;t want to call it too often. Rather, we want to call it once a minute or something like that. We&#8217;re going to wrap this functionality in a custom component. In the custom component we&#8217;re going to reply on a Client EventPool event to talk to our component rather than call into it directly. This way, we don&#8217;t really need to have a link to the component.<br />
First, for posterity, let&#8217;s redefine our Client EventPool. (<a href="https://seejoelprogram.wordpress.com/2008/07/31/a-client-event-pool-in-javascript/" target="_blank">For more information on the Client EventPool, see this post</a>.)</p>
<pre>_EventPool = <span style="color:blue;">function</span>() {
    _EventPool.initializeBase(<span style="color:blue;">this</span>);
};
_EventPool.prototype = {
    addEvent: <span style="color:blue;">function</span>(name, handler) {
        <span style="color:blue;">this</span>.get_events().addHandler(name, handler);
    },
    removeEvent: <span style="color:blue;">function</span>(name, handler) {
        <span style="color:blue;">this</span>.get_events().removeHandler(name, handler);
    },
    raiseEvent: <span style="color:blue;">function</span>(name, source, args) {
        <span style="color:blue;">var </span>handler = <span style="color:blue;">this</span>.get_events().getHandler(name);
        <span style="color:blue;">if </span>(handler) {
            handler(source, args);
        }
    }
};
_EventPool.registerClass(<span style="color:#a31515;">"_EventPool"</span>, Sys.Component);
<span style="color:blue;">var </span>$evp = $create(_EventPool, { <span style="color:#a31515;">"id"</span>: <span style="color:#a31515;">"EventPool" </span>}, <span style="color:blue;">null</span>, <span style="color:blue;">null</span>, <span style="color:blue;">null</span>);</pre>
<p>Now we can define our OutOfBandSessionValidator component and a custom event args class:</p>
<pre class="code">RevalidateSessionArgs = <span style="color:blue;">function</span>(ticks) {
    RevalidateSessionArgs.initializeBase(<span style="color:blue;">this</span>);
    <span style="color:blue;">this</span>._ticks = ticks;
};
RevalidateSessionArgs.prototype = {
    get_ticks: <span style="color:blue;">function</span>() { <span style="color:blue;">return this</span>._ticks; }
};
RevalidateSessionArgs.registerClass(<span style="color:#a31515;">"RevalidateSessionArgs"</span>, Sys.EventArgs);

_OutOfBandSessionValidator = <span style="color:blue;">function</span>() {
    _OutOfBandSessionValidator.initializeBase(<span style="color:blue;">this</span>);
    <span style="color:blue;">this</span>._revalidateSessionDelegate = <span style="color:blue;">null</span>;
    <span style="color:blue;">this</span>._lastTimeSessionWasValidated = <span style="color:blue;">null</span>;
    <span style="color:blue;">this</span>._delay = 60000; <span style="color:green;">// default to 60 seconds.
</span>};

_OutOfBandSessionValidator.prototype = {
    set_delay: <span style="color:blue;">function</span>(value) { <span style="color:blue;">this</span>._delay = value; },
    get_delay: <span style="color:blue;">function</span>() { <span style="color:blue;">return this</span>._delay; },

    initialize: <span style="color:blue;">function</span>() {
        _OutOfBandSessionValidator.callBaseMethod(<span style="color:blue;">this</span>, <span style="color:#a31515;">'initialize'</span>);
        <span style="color:blue;">this</span>._revalidateSessionDelegate = Function.createDelegate(<span style="color:blue;">this</span>, <span style="color:blue;">this</span>._revalidateSession);
        $evp.addEvent(<span style="color:#a31515;">"RevalidateSession"</span>, <span style="color:blue;">this</span>._revalidateSessionDelegate);
    },

    dispose: <span style="color:blue;">function</span>() {
        <span style="color:blue;">if </span>(<span style="color:blue;">this</span>._revalidateSessionDelegate !== <span style="color:blue;">null</span>) {
            $evp.removeEvent(<span style="color:#a31515;">"RevalidateSession"</span>, <span style="color:blue;">this</span>._revalidateSessionDelegate);
            <span style="color:blue;">this</span>._revalidateSessionDelegate = <span style="color:blue;">null</span>;
        }
        _OutOfBandSessionValidator.callBaseMethod(<span style="color:blue;">this</span>, <span style="color:#a31515;">'dispose'</span>);
    },

    _revalidateSession: <span style="color:blue;">function</span>(sender, args) {
        Sys.Debug.trace(<span style="color:#a31515;">"_revalidatingSession"</span>);
        <span style="color:blue;">var </span>revalidate = <span style="color:blue;">false</span>;
        <span style="color:blue;">if </span>(<span style="color:blue;">this</span>._lastTimeSessionWasValidated === <span style="color:blue;">null</span>) {
            revalidate = <span style="color:blue;">true</span>;
        }
        <span style="color:blue;">else if </span>((args.get_ticks() - <span style="color:blue;">this</span>._lastTimeSessionWasValidated) &gt; <span style="color:blue;">this</span>._delay) {
            revalidate = <span style="color:blue;">true</span>;
        }

        <span style="color:blue;">if </span>(revalidate) {
            Sys.Debug.trace(<span style="color:#a31515;">"Executing call to OutOfBandSessionValidator.ashx"</span>);
            <span style="color:blue;">this</span>._lastTimeSessionWasValidated = args.get_ticks();
            <span style="color:blue;">var </span>wRequest = <span style="color:blue;">new </span>Sys.Net.WebRequest();
            wRequest.set_httpVerb(<span style="color:#a31515;">"GET"</span>);
            wRequest.set_url(<span style="color:#a31515;">"OutOfBandSessionValidator.ashx?d=" </span>+ args.get_ticks());

            <span style="color:blue;">var </span>executor = <span style="color:blue;">new </span>Sys.Net.XMLHttpExecutor();
            wRequest.set_executor(executor);
            executor.executeRequest();
        }
    }
};
_OutOfBandSessionValidator.registerClass(<span style="color:#a31515;">"_OutOfBandSessionValidator"</span>, Sys.Component);
$create(_OutOfBandSessionValidator, { <span style="color:#a31515;">"id"</span>: <span style="color:#a31515;">"OutOfBandSessionValidator" </span>}, <span style="color:blue;">null</span>, <span style="color:blue;">null</span>, <span style="color:blue;">null</span>);

The _OutOfBandSessionValidator component is quite simple. In it's initialize method we wire up a delegate to the "RevalidateSession" event</pre>
<pre class="code">initialize: <span style="color:blue;">function</span>() {
    _OutOfBandSessionValidator.callBaseMethod(<span style="color:blue;">this</span>, <span style="color:#a31515;">'initialize'</span>);
    <span style="color:blue;">this</span>._revalidateSessionDelegate = Function.createDelegate(<span style="color:blue;">this</span>, <span style="color:blue;">this</span>._revalidateSession);
    $evp.addEvent(<span style="color:#a31515;">"RevalidateSession"</span>, <span style="color:blue;">this</span>._revalidateSessionDelegate);
},</pre>
<p><a href="http://11011.net/software/vspaste"></a><br />
In the dispose method we clear out this event handler</p>
<pre class="code">dispose: <span style="color:blue;">function</span>() {
    <span style="color:blue;">if </span>(<span style="color:blue;">this</span>._revalidateSessionDelegate !== <span style="color:blue;">null</span>) {
        $evp.removeEvent(<span style="color:#a31515;">"RevalidateSession"</span>, <span style="color:blue;">this</span>._revalidateSessionDelegate);
        <span style="color:blue;">this</span>._revalidateSessionDelegate = <span style="color:blue;">null</span>;
    }
    _OutOfBandSessionValidator.callBaseMethod(<span style="color:blue;">this</span>, <span style="color:#a31515;">'dispose'</span>);
},</pre>
<p><a href="http://11011.net/software/vspaste"></a><br />
The other method, _revalidateSession, which is executed whenever the &#8220;RevalidateSession&#8221; event is raised, is responsible for calling our OutOfBandSessionValidator handler not more than whatever delay we set.</p>
<pre class="code">_revalidateSession: <span style="color:blue;">function</span>(sender, args) {
    Sys.Debug.trace(<span style="color:#a31515;">"_revalidatingSession"</span>);
    <span style="color:blue;">var </span>revalidate = <span style="color:blue;">false</span>;
    <span style="color:blue;">if </span>(<span style="color:blue;">this</span>._lastTimeSessionWasValidated === <span style="color:blue;">null</span>) {
        revalidate = <span style="color:blue;">true</span>;
    }
    <span style="color:blue;">else if </span>((args.get_ticks() - <span style="color:blue;">this</span>._lastTimeSessionWasValidated) &gt; <span style="color:blue;">this</span>._delay) {
        revalidate = <span style="color:blue;">true</span>;
    }

    <span style="color:blue;">if </span>(revalidate) {
        Sys.Debug.trace(<span style="color:#a31515;">"Executing call to OutOfBandSessionValidator.ashx"</span>);
        <span style="color:blue;">this</span>._lastTimeSessionWasValidated = args.get_ticks();
        <span style="color:blue;">var </span>wRequest = <span style="color:blue;">new </span>Sys.Net.WebRequest();
        wRequest.set_httpVerb(<span style="color:#a31515;">"GET"</span>);
        wRequest.set_url(<span style="color:#a31515;">"OutOfBandSessionValidator.ashx</span><span style="color:#a31515;">?d=" </span>+ args.get_ticks()); 

        <span style="color:blue;">var </span>executor = <span style="color:blue;">new </span>Sys.Net.XMLHttpExecutor();
        wRequest.set_executor(executor);
        executor.executeRequest();
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>In the _revaidateSession method, the args parameter is of type RevalidateSessionArgs. This custom arguments class contains one property, get_ticks(), which simply holds a ticks value. This value&#8217;s intended purpose is to hold the current ticks of the date/time when of when the event args were created. It then performs some checking to make sure that we haven&#8217;t initiated a request to OutOfBandSessionValidator.ashx with the delay and then sends a non-cacheable GET request to the OutOfBandSessionValidator.ashx handler.</p>
<p>To use the OutOfBandSessionValidator we raise the RevalidateSession event like so:</p>
<pre class="code">$evp.raiseEvent(<span style="color:#a31515;">"RevalidateSession"</span>, <span style="color:blue;">this</span>, <span style="color:blue;">new </span>RevalidateSessionArgs(<span style="color:blue;">new </span>Date().getTime()));</pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<p>Now that we have a mechanism for calling the OutOfBandSessionValidator.ashx by raising an event, we can write a small test page that raises the event every 5 seconds. To really illustrate that our mechanism works, we&#8217;re going to set the ASP.NET Session timeout to 1 minute in the web.config file.</p>
<pre class="code">        <span style="color:blue;">&lt;</span><span style="color:#a31515;">sessionState  </span><span style="color:red;">mode</span><span style="color:blue;">=</span>"<span style="color:blue;">InProc</span>" <span style="color:red;">cookieless</span><span style="color:blue;">=</span>"<span style="color:blue;">true</span>" <span style="color:red;">timeout</span><span style="color:blue;">=</span>"<span style="color:blue;">1</span>" <span style="color:blue;">/&gt;
    &lt;/</span><span style="color:#a31515;">system.web</span><span style="color:blue;">&gt;
</span></pre>
<p>Here&#8217;s our test page&#8217;s markup. Note that we have three buttons on the page. The first one causes postback and refreshes the label with the current Session&#8217;s information. The other two start and stop the raising of the event.</p>
<pre class="code"><span style="color:blue;">&lt;</span><span style="color:#a31515;">body</span><span style="color:blue;">&gt;
    &lt;</span><span style="color:#a31515;">form </span><span style="color:red;">id</span><span style="color:blue;">="form1" </span><span style="color:red;">runat</span><span style="color:blue;">="server"&gt;
    &lt;</span><span style="color:#a31515;">asp</span><span style="color:blue;">:</span><span style="color:#a31515;">ScriptManager </span><span style="color:red;">ID</span><span style="color:blue;">="SM1" </span><span style="color:red;">runat</span><span style="color:blue;">="server"&gt;
        &lt;</span><span style="color:#a31515;">Scripts</span><span style="color:blue;">&gt;
            &lt;</span><span style="color:#a31515;">asp</span><span style="color:blue;">:</span><span style="color:#a31515;">ScriptReference </span><span style="color:red;">Path</span><span style="color:blue;">="~/JS.js" /&gt;
        &lt;/</span><span style="color:#a31515;">Scripts</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">asp</span><span style="color:blue;">:</span><span style="color:#a31515;">ScriptManager</span><span style="color:blue;">&gt;
    &lt;</span><span style="color:#a31515;">div</span><span style="color:blue;">&gt;
        &lt;</span><span style="color:#a31515;">asp</span><span style="color:blue;">:</span><span style="color:#a31515;">Label </span><span style="color:red;">ID</span><span style="color:blue;">="lblNewSession" </span><span style="color:red;">runat</span><span style="color:blue;">="server" /&gt;
        &lt;</span><span style="color:#a31515;">asp</span><span style="color:blue;">:</span><span style="color:#a31515;">Button </span><span style="color:red;">ID</span><span style="color:blue;">="btnCausePostback" </span><span style="color:red;">runat</span><span style="color:blue;">="server" </span><span style="color:red;">Text</span><span style="color:blue;">="Cause Postback" /&gt;
    &lt;/</span><span style="color:#a31515;">div</span><span style="color:blue;">&gt;
    &lt;</span><span style="color:#a31515;">input </span><span style="color:red;">type</span><span style="color:blue;">="button" </span><span style="color:red;">id</span><span style="color:blue;">="btnStopInterval" </span><span style="color:red;">disabled</span><span style="color:blue;">='disabled' </span><span style="color:red;">value</span><span style="color:blue;">="Stop Interval"
        </span><span style="color:red;">onclick</span><span style="color:blue;">="window.clearInterval(window._intervalId);
                 $get('btnStartInterval').disabled = false;
                 $get('btnStopInterval').disabled=true; " /&gt;
    &lt;</span><span style="color:#a31515;">input </span><span style="color:red;">type</span><span style="color:blue;">="button" </span><span style="color:red;">id</span><span style="color:blue;">="btnStartInterval" </span><span style="color:red;">value</span><span style="color:blue;">="Start Interval"
        </span><span style="color:red;">onclick</span><span style="color:blue;">="window._intervalId=window.setInterval(window.fn, 5000);
        $get('btnStartInterval').disabled = true;
        $get('btnStopInterval').disabled = false;" /&gt;
    &lt;/</span><span style="color:#a31515;">form</span><span style="color:blue;">&gt;
&lt;/</span><span style="color:#a31515;">body</span><span style="color:blue;">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Here&#8217;s the test page&#8217;s code behind.</p>
<pre class="code"><span style="color:blue;">public partial class </span><span style="color:#2b91af;">_Default </span>: <span style="color:#2b91af;">Page
</span>{
    <span style="color:blue;">protected void </span>Page_Load(<span style="color:blue;">object </span>sender, <span style="color:#2b91af;">EventArgs </span>e)
    {
        Session[<span style="color:#a31515;">"lastAcessTime"</span>] = <span style="color:#2b91af;">DateTime</span>.Now;
        <span style="color:blue;">if </span>(<span style="color:blue;">this</span>.Session.IsNewSession)
        {
            <span style="color:blue;">this</span>.lblNewSession.Text = <span style="color:#a31515;">"New Session: " </span>+ <span style="color:blue;">this</span>.Session.SessionID;
        }
        <span style="color:blue;">else
        </span>{
            <span style="color:blue;">this</span>.lblNewSession.Text = <span style="color:#a31515;">"Existing Session: " </span>+ <span style="color:blue;">this</span>.Session.SessionID;
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<p>Here&#8217;s how the page looks when we initially load it.</p>
<p><a href="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/firstload.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/firstload-thumb.jpg?w=462&#038;h=154" border="0" alt="FirstLoad" width="462" height="154" /></a><br />
After waiting 30 seconds or so, and clicking the &#8220;Cause Postback&#8221; button, we see that we&#8217;re working with an existing Session.</p>
<p><a href="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/existingsession.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/existingsession-thumb.jpg?w=466&#038;h=175" border="0" alt="ExistingSession" width="466" height="175" /></a></p>
<p>After waiting more than one minute and clicking the &#8220;Cause Postback&#8221; button, we see that the Session is again new.</p>
<p><a href="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/newsession.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/newsession-thumb.jpg?w=467&#038;h=142" border="0" alt="NewSession" width="467" height="142" /></a><br />
Now we turn on the interval that is going to raise our RevalidateSession event by clicking the &#8220;Start&#8221; button.</p>
<p><a href="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/interval-started.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/interval-started-thumb.jpg?w=445&#038;h=143" border="0" alt="Interval Started" width="445" height="143" /></a><br />
Note: for this test, I reduced the delay between requests from 60 seconds to 20 seconds.<br />
Looking at the debug window of Visual Studio, we can see that our event is being raised every 5 seconds, but besides the first request, not until the 4th request (20 second mark) do we see the debug message that we&#8217;ve initiated a request to the OutOfBandSessionValidator.ashx.</p>
<p><a href="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/revalidatingsession.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/revalidatingsession-thumb.jpg?w=489&#038;h=294" border="0" alt="RevalidatingSession" width="489" height="294" /></a></p>
<p>Again, after another 4 requests we see the request to the OutOfBandSessionValidator.ashx</p>
<p><a href="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/multiplecallsrevalidationsession.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/multiplecallsrevalidationsession-thumb.jpg?w=502&#038;h=330" border="0" alt="MultipleCallsRevalidationSession" width="502" height="330" /></a><br />
Now when I click the &#8220;Cause Postback&#8221; I get the existing Session message</p>
<p><a href="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/validsession.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/validsession-thumb.jpg?w=460&#038;h=145" border="0" alt="ValidSession" width="460" height="145" /></a><br />
When I click the &#8220;Stop&#8221; button, wait about a minute or so and then click the &#8220;Cause Postback&#8221; button, you&#8217;ll see that the Session has started over.</p>
<p><a href="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/newsessionagain.jpg"><img style="border-right:0;border-top:0;border-left:0;border-bottom:0;" src="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/newsessionagain-thumb.jpg?w=456&#038;h=152" border="0" alt="NewSessionAgain" width="456" height="152" /></a><br />
So there you have it. My take on how to keep an ASP.NET Session alive in an Ajax application.</p>
<p>My final thought is this. It doesn&#8217;t make much sense to raise the event every 10 seconds or something like in order to keep the Session alive. Session timeouts are there for a reason. If you never wanted the Session to timeout a better way would be to increase the Session timeout to some ridiculous number. Rather, it is much better to raise the event in response to a user&#8217;s action. The user panned the map, requested a property detail, clicked a drop down list, etc. If you get real clever, you&#8217;ll figure out that you should centralize this event raising and figure out a way to write the code once and have it executed automatically.<a href="http://www.amazon.com/Essential-ASP-Net-Ajax-Server-Controls/dp/0321514440/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1199425487&amp;sr=8-1"></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://seejoelprogram.wordpress.com/2008/11/10/maintaining-aspnet-session-state-in-an-ajax-application/feed/</wfw:commentRss>
			<slash:comments>19</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/b36ab77f5bbc03913a2a397c3960b1762bd883326274bdbee69e06549aaca06c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jrumerman</media:title>
		</media:content>

		<media:content url="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/firstload-thumb.jpg" medium="image">
			<media:title type="html">FirstLoad</media:title>
		</media:content>

		<media:content url="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/existingsession-thumb.jpg" medium="image">
			<media:title type="html">ExistingSession</media:title>
		</media:content>

		<media:content url="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/newsession-thumb.jpg" medium="image">
			<media:title type="html">NewSession</media:title>
		</media:content>

		<media:content url="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/interval-started-thumb.jpg" medium="image">
			<media:title type="html">Interval Started</media:title>
		</media:content>

		<media:content url="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/revalidatingsession-thumb.jpg" medium="image">
			<media:title type="html">RevalidatingSession</media:title>
		</media:content>

		<media:content url="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/multiplecallsrevalidationsession-thumb.jpg" medium="image">
			<media:title type="html">MultipleCallsRevalidationSession</media:title>
		</media:content>

		<media:content url="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/validsession-thumb.jpg" medium="image">
			<media:title type="html">ValidSession</media:title>
		</media:content>

		<media:content url="https://seejoelprogram.wordpress.com/wp-content/uploads/2008/11/newsessionagain-thumb.jpg" medium="image">
			<media:title type="html">NewSessionAgain</media:title>
		</media:content>
	</item>
		<item>
		<title>Fixing Sys.Application.initialize &#8230; Again</title>
		<link>https://seejoelprogram.wordpress.com/2008/10/03/fixing-sysapplicationinitialize-again/</link>
					<comments>https://seejoelprogram.wordpress.com/2008/10/03/fixing-sysapplicationinitialize-again/#comments</comments>
		
		<dc:creator><![CDATA[Joel Rumerman]]></dc:creator>
		<pubDate>Fri, 03 Oct 2008 21:11:23 +0000</pubDate>
				<category><![CDATA[ASP.NET AJAX]]></category>
		<guid isPermaLink="false">http://seejoelprogram.wordpress.com/2008/10/03/fixing-sysapplicationinitialize-again/</guid>

					<description><![CDATA[Download the text version of the changes In a past post, I highlighted a problem with the method ASP.NET AJAX uses to determine if the DOM is ready to be modified. (Other developers have since commented that they&#8217;ve seen this problem in the wild.) I followed that post with another one where I provided code [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Download the <a href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=JoelRumerman&amp;DownloadId=3303" target="_blank">text version of the changes</a></strong></p>
<p>In a past <a href="https://seejoelprogram.wordpress.com/2008/06/08/when-sysapplicationinitialize-causes-operation-aborted-in-ie/" target="_blank">post</a>, I highlighted a problem with the method ASP.NET AJAX uses to determine if the DOM is ready to be modified. (Other <a href="http://mattberseth.com/blog/2008/08/ie_operation_aborted_and_msdn.html" target="_blank">developers</a> have since commented that they&#8217;ve seen this problem in the wild.) I followed that post with <a href="https://seejoelprogram.wordpress.com/2008/06/10/update-fixing-sysapplicationinitialize/" target="_blank">another one</a> where I provided code changes to fix the problem. Through comments on that post, talking with other developers, and reading other people&#8217;s blogs, I determined that it was a little bit unelegant and didn&#8217;t take into account all situations.</p>
<p> <span id="more-151"></span></p>
<p>So, I wanted to take a few minutes and revisit this topic; hopefully for the last time, and provide a more complete ASP.NET AJAX solution for this problem.</p>
<p>The code I&#8217;m about to cover wasn&#8217;t designed, developed, or thought up by me. Rather it&#8217;s a mis-mash of different developers working on a problem. You could say it&#8217;s open source at its best. The <a href="http://javascript.nwbox.com/ContentLoaded/" target="_blank">code</a> I&#8217;m actually going to provide comes from <cite><a href="http://www.iport.it">Diego Perini</a></cite>. He has put together a complete solution that works across all browsers. He, in turn, borrows from Dean Edwards and others. </p>
<p>So, I&#8217;ve adapted his code to the ASP.NET AJAX environment.</p>
<p>First, here&#8217;s the new version of <u>Sys.Application.initialize</u>:</p>
<pre class="code"><span style="color:blue;">  function </span>Sys$_Application$initialize() {
      <span style="color:blue;">if</span>(!<span style="color:blue;">this</span>._initialized &amp;&amp; !<span style="color:blue;">this</span>._initializing) {
          <span style="color:blue;">this</span>._initializing = <span style="color:blue;">true</span>;
          <span style="color:blue;">var </span>u = window.navigator.userAgent.toLowerCase(),
              v = parseFloat(u.match(/.+(?:rv|it|ml|ra|ie)[\/: ]([\d.]+)/)[1]);

          <span style="color:blue;">var </span>initializeDelegate = Function.createDelegate(<span style="color:blue;">this</span>, <span style="color:blue;">this</span>._doInitialize);
          
          <span style="color:blue;">if </span>(/WebKit/i.test(u) &amp;&amp; v &lt; 525.13) 
          { 
              <span style="color:blue;">this</span>._load_timer = window.setInterval(<span style="color:blue;">function</span>() 
              {
                  <span style="color:blue;">if </span>(/loaded|complete/.test(document.readyState))
                  {
                      initializeDelegate(); 
                  }
              }, 10);
          }
          <span style="color:blue;">else if </span>(/msie/.test(u) &amp;&amp; !window.opera)
          {
              document.attachEvent(<span style="color:#a31515;">'onreadystatechange'</span>,
                  <span style="color:blue;">function </span>(e) {
                      <span style="color:blue;">if </span>(document.readyState == <span style="color:#a31515;">'complete'</span>) {
                          document.detachEvent(<span style="color:#a31515;">'on'</span>+e.type, arguments.callee);
                          initializeDelegate();
                      }
                  }
              );
              <span style="color:blue;">if </span>(window == top) {
                  (<span style="color:blue;">function </span>() {
                      <span style="color:blue;">try </span>{
                          document.documentElement.doScroll(<span style="color:#a31515;">'left'</span>);
                      } <span style="color:blue;">catch </span>(e) {
                          setTimeout(arguments.callee, 10);
                          <span style="color:blue;">return</span>;
                      }
                      initializeDelegate();
                  })();
              }

          }
          <span style="color:blue;">else if </span>(document.addEventListener
              &amp;&amp;  ((/opera\<span style="color:green;">//.test(u) &amp;&amp; v &gt; 9) ||
                  </span>(/gecko\<span style="color:green;">//.test(u) &amp;&amp; v &gt;= 1.8) ||
                  </span>(/khtml\<span style="color:green;">//.test(u) &amp;&amp; v &gt;= 4.0) ||
                  </span>(/webkit\<span style="color:green;">//.test(u) &amp;&amp; v &gt;= 525.13))) {
              </span>document.addEventListener(<span style="color:#a31515;">"DOMContentLoaded"</span>, initializeDelegate, <span style="color:blue;">false</span>);
          }
          <span style="color:blue;">else
          </span>{
              $addHandler(window, <span style="color:#a31515;">"load"</span>, initializeDelegate);
          }   
      }
  }</pre>
<p>Here&#8217;s the _<u>doInitialize</u> method:</p>
<pre class="code"><span style="color:blue;">  function </span>Sys$_Application$_doInitialize() {
       <strong><span style="color:blue;">if </span>(<span style="color:blue;">this</span>._initialized) {
           <span style="color:blue;">return</span>;
       }
       Sys._Application.callBaseMethod(<span style="color:blue;">this</span>, <span style="color:#a31515;">'initialize'</span>);
       <span style="color:blue;">if </span>(<span style="color:blue;">this</span>._load_timer !== <span style="color:blue;">null</span>)
       {
           clearInterval(<span style="color:blue;">this</span>._load_timer);
           <span style="color:blue;">this</span>._load_timer = <span style="color:blue;">null</span>;
       }</strong>
       <span style="color:blue;">var </span>handler = <span style="color:blue;">this</span>.get_events().getHandler(<span style="color:#a31515;">"init"</span>);
       <span style="color:blue;">if </span>(handler) {
           <span style="color:blue;">this</span>.beginCreateComponents();
           handler(<span style="color:blue;">this</span>, Sys.EventArgs.Empty);
           <span style="color:blue;">this</span>.endCreateComponents();
       }
       <span style="color:blue;">if </span>(Sys.WebForms) {
           <span style="color:blue;">this</span>._beginRequestHandler = Function.createDelegate(<span style="color:blue;">this</span>, <span style="color:blue;">this</span>._onPageRequestManagerBeginRequest);
           Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(<span style="color:blue;">this</span>._beginRequestHandler);
           <span style="color:blue;">this</span>._endRequestHandler = Function.createDelegate(<span style="color:blue;">this</span>, <span style="color:blue;">this</span>._onPageRequestManagerEndRequest);
           Sys.WebForms.PageRequestManager.getInstance().add_endRequest(<span style="color:blue;">this</span>._endRequestHandler);
       }
       
       <span style="color:blue;">var </span>loadedEntry = <span style="color:blue;">this</span>.get_stateString();
       <span style="color:blue;">if </span>(loadedEntry !== <span style="color:blue;">this</span>._currentEntry) {
           <span style="color:blue;">this</span>._navigate(loadedEntry);
       }

       <span style="color:blue;">this</span>.raiseLoad();
       <span style="color:blue;">this</span>._initializing = <span style="color:blue;">false</span>;
   }</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Finally, here&#8217;s the <u>Sys.Application._loadHandler</u> method, which hasn&#8217;t changed since the first version.</p>
<pre class="code"><span style="color:blue;">function </span>Sys$_Application$_loadHandler() {
    <span style="color:blue;">if</span>(<span style="color:blue;">this</span>._loadHandlerDelegate) {
        Sys.UI.DomEvent.removeHandler(window, <span style="color:#a31515;">"load"</span>, <span style="color:blue;">this</span>._loadHandlerDelegate);
        <span style="color:blue;">this</span>._loadHandlerDelegate = <span style="color:blue;">null</span>;
    }
    <span style="color:blue;">this</span>._initializing = <span style="color:blue;">true</span>;
    <span style="color:blue;">this</span>._doInitialize();
}</pre>
<p><a href="http://11011.net/software/vspaste"></a>Just like last time, the majority of the work takes place in the initalize method.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://seejoelprogram.wordpress.com/2008/10/03/fixing-sysapplicationinitialize-again/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/b36ab77f5bbc03913a2a397c3960b1762bd883326274bdbee69e06549aaca06c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jrumerman</media:title>
		</media:content>
	</item>
		<item>
		<title>Encosia.com Control Contest</title>
		<link>https://seejoelprogram.wordpress.com/2008/09/09/encosiacom-control-contest/</link>
					<comments>https://seejoelprogram.wordpress.com/2008/09/09/encosiacom-control-contest/#respond</comments>
		
		<dc:creator><![CDATA[Joel Rumerman]]></dc:creator>
		<pubDate>Wed, 10 Sep 2008 04:07:14 +0000</pubDate>
				<category><![CDATA[ASP.NET AJAX]]></category>
		<guid isPermaLink="false">http://seejoelprogram.wordpress.com/2008/09/09/encosiacom-control-contest/</guid>

					<description><![CDATA[Dave Ward of Encosia.com has setup a control writing contest where you can win one of three free copies of Adam and my book Advanced ASP.NET AJAX Server Controls for .NET Framework 3.5. (Next time, I&#8217;m definitely coming up with a shorter title!) Adam and I are going to be judging along with Dave and [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Dave Ward of Encosia.com has setup a <a href="http://encosia.com/2008/09/09/contribute-to-open-source-get-a-shot-at-a-free-book/" target="_blank">control writing contest</a> where you can win one of three free copies of Adam and my book <a href="http://www.amazon.com/Advanced-Controls-Framework-Microsoft-Development/dp/0321514440/" target="_blank">Advanced ASP.NET AJAX Server Controls for .NET Framework 3.5</a>. (Next time, I&#8217;m definitely coming up with a shorter title!) <a href="http://team.interknowlogy.com/blogs/adamcalderon/default.aspx" target="_blank">Adam</a> and I are going to be judging along with Dave and there are many ways to win so hop over to his site, <a href="http://encosia.com/2008/09/09/contribute-to-open-source-get-a-shot-at-a-free-book/" target="_blank">read the post</a>, and write some code (or documentation)! </p>
<p>Good luck and thanks for putting it together Dave!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://seejoelprogram.wordpress.com/2008/09/09/encosiacom-control-contest/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/b36ab77f5bbc03913a2a397c3960b1762bd883326274bdbee69e06549aaca06c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jrumerman</media:title>
		</media:content>
	</item>
		<item>
		<title>Adding Google Chrome to ASP.NET AJAX</title>
		<link>https://seejoelprogram.wordpress.com/2008/09/04/adding-google-chrome-to-aspnet-ajax/</link>
					<comments>https://seejoelprogram.wordpress.com/2008/09/04/adding-google-chrome-to-aspnet-ajax/#comments</comments>
		
		<dc:creator><![CDATA[Joel Rumerman]]></dc:creator>
		<pubDate>Fri, 05 Sep 2008 04:21:09 +0000</pubDate>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">http://seejoelprogram.wordpress.com/?p=125</guid>

					<description><![CDATA[12/15/2008 &#8211; Two things to update: First, sources at Microsoft confirmed this bug for me and said that a fix was already completed for v-next. I&#8217;m not sure when the next release will take place; if it will be with VS 2010 or sometime earlier, but they have it fixed. Second, Jason Kealey has a [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>
<b>12/15/2008 &#8211; Two things to update:</b><br />
</p>
<blockquote><p>
First, sources at Microsoft confirmed this bug for me and said that a fix was already completed for v-next. I&#8217;m not sure when the next release will take place; if it will be with VS 2010 or sometime earlier, but they have it fixed.<br />
<br />
Second, <a href="http://blog.lavablast.com/author/JKealey.aspx">Jason Kealey</a> has a fix that is less intrusive than the one I suggested here. You can find it <a href="http://blog.lavablast.com/post/2008/10/Gotcha-WebKit-(Safari-3-and-Google-Chrome)-Bug-with-ASPNET-AJAX.aspx">here</a>
</p></blockquote>
<p>Since the rest of the tech-world is talking about and trying Google Chrome, I thought that I&#8217;d give it a whirl and see how it interacted with ASP.NET AJAX. I&#8217;ve worked on a couple of ASP.NET AJAX applications for work (including a public website: <a href="http://showcase.costar.com">http://showcase.costar.com</a>) and have a bunch of small test application that I&#8217;ve written for other purposes and was curious to see how those held up when accessed with Chrome. For the most part, with the smaller applications the browser worked as expected. I had almost no layout issues (as we program for IE6, IE7, FF2, and FF3) and almost no JS problems. But, when I ran ShowCase, which uses UpdatePanels to load large swathes of a page and in doing so loads external scripts dynamically, the application broke when accessing the mapping portion of the application. Since I was responsible for this part of the application, I needed to investigate further.</p>
<p><span id="more-125"></span></p>
<p>Through Fiddler, which Chrome interacts with nicely by default, I discovered that my scripts weren&#8217;t loading. Furthermore, through Chrome&#8217;s JavaScript console I learned that a JS error was being thrown. The error thrown was the one where it says the external script at xyz.js doesn&#8217;t contain a call to Sys.Application.notifyScriptLoaded(). Well, all my scripts contain this call and so this was a red herring, but set me in the right direction.</p>
<p style="margin-top:6px;">Thinking about it, I remembered that script loading during a partial postback is a browser specific task and I wondered what code path Google Chrome was following since it isn&#8217;t a known browser to ASP.NET AJAX. The first thing I needed to discover was what browser ASP.NET AJAX thought it was interacting with. To my surprise, <strong>ASP.NET AJAX thought Chrome was Safari</strong>.</p>
<p style="margin-top:6px;">I discovered this using Chrome&#8217;s JavaScript console and executing the &#8220;Sys.Browser.name&#8221; command, which outputted the value &#8220;Safari.&#8221; (BTW, the IntelliSense in the console window is amazing.) At first, I thought that Safari might be the default browser when the ASP.NET AJAX code can&#8217;t figure out what browser it really is. While this would be a bit strange, maybe it made sense when MSFT developed ASP.NET AJAX. So I went hunting inside of MicrosoftAjax.js to figure out why ASP.NET AJAX thought that Chrome was Safari and came to this code.</p>
<pre class="code" style="margin-left:16px;"><span style="color:blue;">if </span>(navigator.userAgent.indexOf(<span style="color:#a31515;">' MSIE '</span>) &gt; -1) {
    Sys.Browser.agent = Sys.Browser.InternetExplorer;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/MSIE (\d+\.\d+)/)[1]);
    <span style="color:blue;">if </span>(Sys.Browser.version &gt;= 8) {
        <span style="color:blue;">if </span>(document.documentMode &gt;= 7) {
            Sys.Browser.documentMode = document.documentMode;
        }
    }
    Sys.Browser.hasDebuggerStatement = <span style="color:blue;">true</span>;
}
<span style="color:blue;">else if </span>(navigator.userAgent.indexOf(<span style="color:#a31515;">' Firefox/'</span>) &gt; -1) {
    Sys.Browser.agent = Sys.Browser.Firefox;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/ Firefox\/(\d+\.\d+)/)[1]);
    Sys.Browser.name = <span style="color:#a31515;">'Firefox'</span>;
    Sys.Browser.hasDebuggerStatement = <span style="color:blue;">true</span>;
}
<strong><span style="color:blue;">else if </span>(navigator.userAgent.indexOf(<span style="color:#a31515;">' AppleWebKit/'</span>) &gt; -1) {
    Sys.Browser.agent = Sys.Browser.Safari;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/ AppleWebKit\/(\d+(\.\d+)?)/)[1]);
    Sys.Browser.name = <span style="color:#a31515;">'Safari'</span>;</strong>
}
<span style="color:blue;">else if </span>(navigator.userAgent.indexOf(<span style="color:#a31515;">'Opera/'</span>) &gt; -1) {
    Sys.Browser.agent = Sys.Browser.Opera;
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Obviously, my initial assertion that Safari might be the default was wrong. Seeing that the code uses the userAgent string to determine the browser, I grabbed the userAgent string of Chrome request in Fiddler:</p>
<p style="margin-top:6px;"><strong>User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13</strong></p>
<p style="margin-top:4px;">As the code above shows, it parses the userAgent string looking for the word &#8221; AppleWebKit/&#8221; and if found (once it didn&#8217;t find &#8221; MSIE &#8221; or &#8221; Firefox/&#8221;) the if-then logic determined that the browser is Safari. Now that I understood why ASP.NET AJAX thought that Chrome was Safari, I also had an idea about why my map was failing to load.</p>
<p style="margin-top:4px;">Searching through MicrosoftAjax.js, I found that there are three code paths that being a &#8220;Safari&#8221; browser alters.</p>
<ol>
<li>JSON Serialization</li>
<li><strong>External script loading and script text processing during a partial postback</strong></li>
<li>Getting a location of an element</li>
</ol>
<p style="margin-top:4px;">Obviously, since the culprit of my problem was that my external scripts weren&#8217;t being loaded during a partial postback, this was the problem I needed to fix. Without knowing exactly what to do, I decided to see if I loaded external script using the default code path instead of the Safari code path, would the scripts load properly. To achieve this I needed to get Chrome to not be recognized as Safari so it would go down the default code path.</p>
<p style="margin-top:4px;">To add the Chrome browser to ASP.NET AJAX, there are two basic steps.</p>
<p style="margin-top:3px;margin-left:2px;">
<p>1. Add a new browser type</p>
<pre class="code" style="margin-left:16px;">Sys.Browser = {};
Sys.Browser.InternetExplorer = {};
Sys.Browser.Firefox = {};
Sys.Browser.Safari = {};
Sys.Browser.Opera = {};
<strong>Sys.Browser.Chrome = {};</strong></pre>
<p>2. Update the if-then logic to search for Chrome</p>
<pre class="code" style="margin-left:16px;"><span style="color:blue;">else if </span>(navigator.userAgent.indexOf(<span style="color:#a31515;">' Firefox/'</span>) &gt; -1) {
    Sys.Browser.agent = Sys.Browser.Firefox;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/ Firefox\/(\d+\.\d+)/)[1]);
    Sys.Browser.name = <span style="color:#a31515;">'Firefox'</span>;
    Sys.Browser.hasDebuggerStatement = <span style="color:blue;">true</span>;
}
<strong><span style="color:blue;">else if </span>(navigator.userAgent.indexOf(<span style="color:#a31515;">' Chrome/'</span>) &gt; -1) {
    Sys.Browser.agent = Sys.Browser.Chrome;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/ Chrome\/(\d+\.\d+)/)[1]);
    Sys.Browser.name = <span style="color:#a31515;">'Chrome'</span>;
    Sys.Browser.hasDebuggerStatement = <span style="color:blue;">true</span>;
}</strong>
<span style="color:blue;">else if </span>(navigator.userAgent.indexOf(<span style="color:#a31515;">' AppleWebKit/'</span>) &gt; -1) {
    Sys.Browser.agent = Sys.Browser.Safari;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/ AppleWebKit\/(\d+(\.\d+)?)/)[1]);
    Sys.Browser.name = <span style="color:#a31515;">'Safari'</span>;</pre>
<p><em><strong>Notice how the Chrome check has to go before the Safari check.</strong></em></p>
<p style="margin-top:6px;">(This is basically the same pattern that&#8217;s talked about <a href="http://forums.asp.net/p/1252014/2549816.aspx">here</a> for Safari 3 before .NET 3.5 SP1 came out. Has anybody else noticed the decreasing font size in the ASP.NET forum&#8217;s when viewing with Chrome?? Hilarious)</p>
<p style="margin-top:6px;">Now, when we run an ASP.NET AJAX site using our custom MicrosoftAjax.js file (to see how to replace Framework scripts with custom ones, <a href="http://aspadvice.com/blogs/joteke/archive/2007/02/16/Replace-_2200_Framework_2200_-scripts-in-ASP.NET-Ajax.aspx">read this article</a>), Sys.Browser.name returns &#8220;Chrome.&#8221;</p>
<p style="margin-top:6px;">So back to ShowCase. Using my customized MicrosoftAjax.js file, ShowCase mapping worked like a champ.</p>
<p style="margin-top:6px;">I&#8217;ll conclude with a caveat. I didn&#8217;t check the Get Location or the Serialization code as it wasn&#8217;t needed for me to get the application up and running, but it <em>looks</em> okay at the moment since my element are positioned correctly and everything is serializing / deserializing. Then again, I don&#8217;t have any unit tests.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://seejoelprogram.wordpress.com/2008/09/04/adding-google-chrome-to-aspnet-ajax/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/b36ab77f5bbc03913a2a397c3960b1762bd883326274bdbee69e06549aaca06c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jrumerman</media:title>
		</media:content>
	</item>
		<item>
		<title>Book Review: Encosia.com</title>
		<link>https://seejoelprogram.wordpress.com/2008/09/04/book-review-encosiacom/</link>
					<comments>https://seejoelprogram.wordpress.com/2008/09/04/book-review-encosiacom/#respond</comments>
		
		<dc:creator><![CDATA[Joel Rumerman]]></dc:creator>
		<pubDate>Thu, 04 Sep 2008 16:51:43 +0000</pubDate>
				<category><![CDATA[ASP.NET AJAX]]></category>
		<guid isPermaLink="false">http://seejoelprogram.wordpress.com/2008/09/04/book-review-encosiacom/</guid>

					<description><![CDATA[Dave Ward, of the site Encosia.com, has put together a great, well-written review of our book, Advanced ASP.NET AJAX Server Controls. Check out the review here: http://encosia.com/2008/09/03/review-advanced-aspnet-ajax-server-controls/ and while you&#8217;re there check out some of Dave&#8217;s extremely useful blog entries on ASP.NET, JavaScript, and other topics. Thx again Dave for the nice review.]]></description>
										<content:encoded><![CDATA[<p>Dave Ward, of the site <a href="http://encosia.com">Encosia.com</a>, has put together a great, well-written review of our book, <a href="http://www.amazon.com/gp/product/0321514440?ie=UTF8&amp;tag=encosia-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321514440">Advanced ASP.NET AJAX Server Controls</a>.</p>
<p>Check out the review here: <a href="http://encosia.com/2008/09/03/review-advanced-aspnet-ajax-server-controls/">http://encosia.com/2008/09/03/review-advanced-aspnet-ajax-server-controls/</a> and while you&#8217;re there check out some of Dave&#8217;s extremely useful blog entries on <a href="http://encosia.com/category/aspnet/">ASP.NET</a>, <a href="http://encosia.com/category/javascript/">JavaScript</a>, and other topics.</p>
<p>Thx again <a href="http://encosia.com">Dave</a> for the nice review.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://seejoelprogram.wordpress.com/2008/09/04/book-review-encosiacom/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/b36ab77f5bbc03913a2a397c3960b1762bd883326274bdbee69e06549aaca06c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jrumerman</media:title>
		</media:content>
	</item>
		<item>
		<title>.NET 3.5 SP1 Doesn&#8217;t Provide Composite Script Registration from an IScriptControl (out-of-the-box)</title>
		<link>https://seejoelprogram.wordpress.com/2008/08/19/net-35-sp1-doesnt-provide-composite-script-registration-from-an-iscriptcontrol-out-of-the-box/</link>
					<comments>https://seejoelprogram.wordpress.com/2008/08/19/net-35-sp1-doesnt-provide-composite-script-registration-from-an-iscriptcontrol-out-of-the-box/#comments</comments>
		
		<dc:creator><![CDATA[Joel Rumerman]]></dc:creator>
		<pubDate>Wed, 20 Aug 2008 05:43:49 +0000</pubDate>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET AJAX]]></category>
		<guid isPermaLink="false">http://seejoelprogram.wordpress.com/2008/08/19/net-35-sp1-doesnt-provide-composite-script-registration-from-an-iscriptcontrol-out-of-the-box/</guid>

					<description><![CDATA[Note: Below the following little story, there&#8217;s a work around that I came up with so if you&#8217;re looking for help, jump down a bit. The Story A story of despair. Here&#8217;s how my evening went. Act I Scene I: I just downloaded and installed the Visual Studio 2008 SP1 / 3.5 SP1 and I&#8217;m [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><em><strong>Note: Below the following little story, there&#8217;s a work around that I came up with so if you&#8217;re looking for help, jump down a bit.</strong></em></p>
<h4><strong>The Story</strong></h4>
<p>A story of despair. Here&#8217;s how my evening went.</p>
<p><em>Act I Scene I</em>: I just downloaded and installed the <a href="http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx" target="_blank">Visual Studio 2008 SP1 / 3.5 SP1</a> and I&#8217;m excited to take a look at how to use the <a href="http://www.asp.net/learn/3.5-SP1/video-296.aspx" target="_blank">Script Combining</a> mechanism. I&#8217;ve been using the ToolScriptManager&#8217;s script combining ability for a while now, and while it is okay, it has its quirks and I was hoping the one in .NET 3.5 SP1 would be better.</p>
<p><em>Act I Scene II</em>: I notice that the ScriptManager has a new templated section called CompositeScript. This is the spot I need to investigate closer.</p>
<p><span id="more-110"></span><em>Act II Scene I</em>: I go to one of my trusty controls (<a href="https://seejoelprogram.wordpress.com/?p=92" target="_blank">AirlinesMiles.cs from my Client Event Pool example</a>) and start to poke around at how I&#8217;m going to get the control&#8217;s script files to be part of the composite script.</p>
<p><em>Act II Scene II</em>: Hmmm&#8230; where&#8217;s the method call on the ScriptManager object to register my ScriptReference with the <a href="http://www.asp.net/downloads/3.5-sp1/Readme/#_Toc198012546" target="_blank">CompositeScript</a> template? Wait, I can&#8217;t find one. What the?</p>
<p>Shouldn&#8217;t there be something like this&#8230;</p>
<pre class="code"><span style="color:blue;">public </span><span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">ScriptReference</span>&gt; GetScriptReferences()
{
    <span style="color:#2b91af;">ScriptReference </span>sr = <span style="color:blue;">new </span><span style="color:#2b91af;">ScriptReference</span>(<span style="color:#a31515;">"ControlLib.UserMileageInput.js"</span>, <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">UserMileageInput</span>).Assembly.FullName); ;
    <strong>sr.RegisterAsCompositeScript</strong> = <span style="color:blue;">true</span>;
    <span style="color:blue;">yield return </span>sr;
}</pre>
<p>or something like this&#8230;</p>
<pre class="code"><span style="color:blue;">protected override void </span>OnPreRender(<span style="color:#2b91af;">EventArgs </span>e)
{
    <span style="color:blue;">base</span>.OnPreRender(e);
<strong>    <span style="color:blue;">bool </span>registerAsCompositeScriptControl = <span style="color:blue;">true</span>;
</strong>    <span style="color:#2b91af;">ScriptManager</span>.GetCurrent(<span style="color:blue;">this</span>.Page).RegisterScriptControl&lt;<span style="color:#2b91af;">UserMileageInput</span>&gt;(<span style="color:blue;">this</span>, <strong>registerAsCompositeScriptControl</strong>);
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>but no, there isn&#8217;t anything like that.</p>
<p><em>Act II Scene III</em>: @#$3234%%$@ #$@ @#$!</p>
<p><em>Act III Scene I</em>: Really &#8230;&#8230; really?? There&#8217;s no built in way for my control to at least <em>ask</em> to be registered with the ScriptManager as a part of the composite script?</p>
<p><em>Act III Scene II</em>: Despair.</p>
<p>Okay, I&#8217;m feeling a bit dramatic tonight, but I&#8217;m at least a little annoyed for feeling a bit overlooked as a control developer.</p>
<p>I get that MSFT probably had a discussion internally about whether to allow controls to register as a composite script or not and that its obvious that the feature didn&#8217;t make it. Maybe they don&#8217;t see it as part of the control developer&#8217;s UX, but only the page developer&#8217;s UX. I don&#8217;t know. Maybe their idea is to have us pull out the ScriptReferences of every single embedded JS file that could possible be loaded by any control and place them into the <a href="http://weblogs.asp.net/tonylombardo/archive/2008/07/28/script-combining-what-s-the-big-deal.aspx" target="_blank">CompositeScript template</a>? I&#8217;m not really sure what MSFT&#8217;s work-around plan is or why the ScriptControlManager wasn&#8217;t updated to support this ability in the first place, but I&#8217;ve got one that at least on the surface works. I shouldn&#8217;t have to though. I should be able to register my scripts as normal as I have for the past 3+ years.</p>
<h4><strong>Workaround</strong></h4>
<p>So I&#8217;ve come up with a little hacky work around for this problem for now and we&#8217;ll see where it takes me&#8230;</p>
<pre class="code"><span style="color:blue;">protected override void </span>OnPreRender(<span style="color:#2b91af;">EventArgs </span>e)
{
      <span style="color:blue;">base</span>.OnPreRender(e);
<strong>      <span style="color:#2b91af;">ScriptReference </span>sr = <span style="color:blue;">new </span><span style="color:#2b91af;">ScriptReference</span>(<span style="color:#a31515;">"ControlLib.UserMileageInput.js"</span>, <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">UserMileageInput</span>).Assembly.FullName);
      sr.NotifyScriptLoaded = <span style="color:blue;">false</span>;
      <span style="color:#2b91af;">ScriptManager</span>.GetCurrent(<span style="color:blue;">this</span>.Page).CompositeScript.Scripts.Add(sr);</strong>
      <span style="color:#2b91af;">ScriptManager</span>.GetCurrent(<span style="color:blue;">this</span>.Page).RegisterScriptControl&lt;<span style="color:#2b91af;">UserMileageInput</span>&gt;(<span style="color:blue;">this</span>);
}</pre>
<pre class="code"><span style="color:blue;">public </span><span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">ScriptReference</span>&gt; GetScriptReferences()
{
    <span style="color:blue;">return null</span>;
}</pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<p>Pretty much I&#8217;ve moved the ScriptReference registration from the GetScriptReferences method to the OnPreRender method. This works in my little example, but I&#8217;ve yet to test it on a larger application.</p>
<h4><strong>Closing</strong></h4>
<p>Finally, for those MSFT folkd who every once in a while peruse my blog, please comment and explain why this turned out this way or if I missed something please let me know. I&#8217;m trying to hold back too much judgement until I hear from you.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://seejoelprogram.wordpress.com/2008/08/19/net-35-sp1-doesnt-provide-composite-script-registration-from-an-iscriptcontrol-out-of-the-box/feed/</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
		
		<media:content url="https://2.gravatar.com/avatar/b36ab77f5bbc03913a2a397c3960b1762bd883326274bdbee69e06549aaca06c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jrumerman</media:title>
		</media:content>
	</item>
	</channel>
</rss>
