<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>.NET slave</title>
    <description>Full featured simplicity in C# and ASP.NET by Mads Kristensen</description>
    <link>http://madskristensen.net/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.5.1.7</generator>
    <language>en-GB</language>
    <blogChannel:blogRoll>http://madskristensen.net/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Mads Kristensen</dc:creator>
    <dc:title>.NET slave</dc:title>
    <geo:lat>5,568,969.000000</geo:lat>
    <geo:long>1,257,128.000000</geo:long>
    <image><link>http://blog.madskristensen.dk/</link><url>http://blog.madskristensen.dk/themes/standard/madskristensen.png</url><title>.NET slave</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/netSlave" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>Use Google's Closure Compiler in C#</title>
      <description>&lt;p&gt;A few days ago, Google released their &lt;a href="http://code.google.com/closure/compiler/"&gt;Closure Compiler project&lt;/a&gt; for optimizing JavaScript. Here&amp;rsquo;s what they write about the Closure Compiler:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The Closure Compiler is a tool for making JavaScript download and run faster. It is a true compiler for JavaScript. Instead of compiling from a source language to machine code, it compiles from JavaScript to better JavaScript. It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The interesting part of the Closure Compiler is that it not only removes whitespace, it also rewrites your JavaScript code to make it smaller and optimizes the code for better performance. My tests show that it can reduce JavaScript files by about 60% - and that&amp;rsquo;s before HTTP compression! Considering how much JavaScript a modern website uses, this is no less than amazing and highly useful.&lt;/p&gt;
&lt;p&gt;The Closure Compiler comes in two flavors &amp;ndash; a Java based command line tool and a RESTful API. I&amp;rsquo;ve been playing around with the API and it works great and very fast.&lt;/p&gt;
&lt;h2&gt;The code&lt;/h2&gt;
&lt;p&gt;The C# class I&amp;rsquo;ve written takes a JavaScript file and passes it through the API and then returns the compressed JavaScript as a string. The class contains one public and one private method and&amp;nbsp;is only 47 lines of code including 16 lines of comments.&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; Compress(&lt;span style="color: blue;"&gt;string&lt;/span&gt; file)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; source = &lt;span style="color: #2b91af;"&gt;File&lt;/span&gt;.ReadAllText(file);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;XmlDocument&lt;/span&gt; xml = CallApi(source);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; xml.SelectSingleNode(&lt;span style="color: #a31515;"&gt;"//compiledCode"&lt;/span&gt;).InnerText;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;XmlDocument&lt;/span&gt; CallApi(&lt;span style="color: blue;"&gt;string&lt;/span&gt; source)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;WebClient&lt;/span&gt; client = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;WebClient&lt;/span&gt;())&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &amp;nbsp; client.Headers.Add(&lt;span style="color: #a31515;"&gt;"content-type"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"application/x-www-form-urlencoded"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; data = &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Format(PostData, &lt;span style="color: #2b91af;"&gt;HttpUtility&lt;/span&gt;.UrlEncode(source));&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt; result = client.UploadString(ApiEndpoint, data);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color: #2b91af;"&gt;XmlDocument&lt;/span&gt; doc = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;XmlDocument&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &amp;nbsp; doc.LoadXml(result);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; doc;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;h2&gt;How to use it&lt;/h2&gt;
&lt;p&gt;You can use the class to do various cool things. You can write a MSBuild or NAnt script that automatically compresses your JavaScript files as part of a continuous integration process or, as I prefer, write a HTTP handler to do the same but at runtime. Remember to output cache the compressed result. Here's an example of using the class from ASP.NET:&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;GoogleClosure&lt;/span&gt; gc = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;GoogleClosure&lt;/span&gt;();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt; script = gc.Compress(Server.MapPath(&lt;span style="color: #a31515;"&gt;"~/script.js"&lt;/span&gt;));&lt;/p&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;Remember that the class doesn't do any exception handling, so you might want to stick that in yourself.&lt;/p&gt;
&lt;h2&gt;Download&lt;br /&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://madskristensen.net/file.axd?file=2009%2f11%2fGoogleClosure.zip"&gt;GoogleClosure.zip (905,00 bytes)&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/i-p2otZTiOw/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/Use-Googles-Closure-Compiler-in-C.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=cbfd9cee-947b-4d73-96b8-d36a438fafe7</guid>
      <pubDate>Sun, 08 Nov 2009 09:26:00 -0500</pubDate>
      <category>ASP.NET</category>
      <category>Client-side</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=cbfd9cee-947b-4d73-96b8-d36a438fafe7</pingback:target>
      <slash:comments>14</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=cbfd9cee-947b-4d73-96b8-d36a438fafe7</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/Use-Googles-Closure-Compiler-in-C.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=cbfd9cee-947b-4d73-96b8-d36a438fafe7</wfw:commentRss>
    <enclosure url="http://madskristensen.net/file.axd?file=2009%2f11%2fGoogleClosure.zip" length="905" type="application/octet-stream" /><feedburner:origLink>http://madskristensen.net/post.aspx?id=cbfd9cee-947b-4d73-96b8-d36a438fafe7</feedburner:origLink></item>
    <item>
      <title>Use iframes with XHTML 1.0 Strict</title>
      <description>&lt;p&gt;Recently I had to use iframes on a website conforming to &lt;em&gt;XHTML 1.0 Strict&lt;/em&gt;. As you might know, the &lt;em&gt;XHTML 1.0 Strict&lt;/em&gt; doctype doesn&amp;rsquo;t allow the use of iframes. The &lt;em&gt;XHTML 1.0 Transitional&lt;/em&gt; doctype on the other hand, does allow you to use iframes, but I don&amp;rsquo;t like to use that doctype. The reason is, as the name implies, that it&amp;rsquo;s a doctype meant for make the transition from HTML into XHTML &amp;ndash; a sort of a temporary solution.&lt;/p&gt;
&lt;p&gt;When building new websites I like to use a strict doctype because it doesn&amp;rsquo;t allow for many of the style and behavioral tags that is much better placed in stylesheets and JavaScript.&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s needed is a doctype that conforms to &lt;em&gt;XHTML 1.0 Strict&lt;/em&gt; which also allows for iframes.&lt;/p&gt;
&lt;h2&gt;A solution&lt;/h2&gt;
&lt;p&gt;What I came up with was very simple, but may be considered a hack by some. Basically, I took the doctype declaration (DTD) of &lt;em&gt;XHTML 1.0 Strict&lt;/em&gt; and added support for iframes. I found how iframes was supported in the transitional DTD and copied it to the Strict DTD. It allows for some attributes like &lt;em&gt;width&lt;/em&gt; and &lt;em&gt;height&lt;/em&gt; that the Strict DTD doesn&amp;rsquo;t, so I removed those and then added support for the &lt;em&gt;allowtransparency&lt;/em&gt; attribute.&lt;/p&gt;
&lt;p&gt;So to make iframes work on your own invalid &lt;em&gt;XHTML 1.0 Strict&lt;/em&gt; page, just replace the doctype at the top of your pages with this new one:&lt;/p&gt;
&lt;pre&gt;&amp;lt;!DOCTYPE html SYSTEM "http://madskristensen.net/custom/xhtml1-iframe.dtd"&amp;gt;&lt;/pre&gt;
&lt;p&gt;I suggest you download and host the DTD on your own server instead of using mine in case I forget to pay my hosting fee.&lt;/p&gt;
&lt;p&gt;Check out the &lt;a href="http://madskristensen.net/custom/xhtml-iframe.htm"&gt;demo of XHTML 1.0 Strict with Iframe&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;A hack?&lt;/h2&gt;
&lt;p&gt;Some might say it&amp;rsquo;s a hack because by using this DTD the page is no longer &lt;em&gt;XHTML 1.0 Strict&lt;/em&gt;. That is correct. It is now something new and different, but completely identical to &lt;em&gt;XHTML 1.0 Strict&lt;/em&gt; with support for iframes. So it&amp;rsquo;s &lt;em&gt;XHTML 1.0 Strict with Iframe&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;XHTML have build in support for custom DTDs and thus this is completely supported and valid XHTML. If you don&amp;rsquo;t like using other doctypes than the few main ones created by the W3C then I have to ask why? What does it give you, your users or the quality of the page that this new one doesn&amp;rsquo;t?&lt;/p&gt;
&lt;p&gt;In my book, it comes down to using a doctype that is based on known standards (&lt;em&gt;XHTML 1.0 Strict&lt;/em&gt; in this case) so it still make sense to other devs when they read the markup. It&amp;rsquo;s also important that the DTD is strict (yep, this DTD is still strict), but most of all it&amp;rsquo;s important that the markup conforms correctly to the DTD so the entire page is valid. Remember, when using custom DTDs your page is still valid XHTML.&lt;/p&gt;
&lt;h3&gt;Note&lt;/h3&gt;
&lt;p&gt;I tried using &lt;em&gt;XHTML 1.1&lt;/em&gt; modules to build the DTD, but it never worked out for me. I got to the point where the iframe tag was valid, but not allowed in any other tags including &lt;em&gt;body&lt;/em&gt;. I couldn&amp;rsquo;t seem to find a way to get full support for it. If you know how, please let me know.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/RoZesj28fdg/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/Use-iframes-with-XHTML-10-Strict.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=ca7b3fe9-2b21-433a-919d-c232fe4ad361</guid>
      <pubDate>Wed, 04 Nov 2009 06:26:00 -0500</pubDate>
      <category>Client-side</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=ca7b3fe9-2b21-433a-919d-c232fe4ad361</pingback:target>
      <slash:comments>17</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=ca7b3fe9-2b21-433a-919d-c232fe4ad361</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/Use-iframes-with-XHTML-10-Strict.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=ca7b3fe9-2b21-433a-919d-c232fe4ad361</wfw:commentRss>
    <feedburner:origLink>http://madskristensen.net/post.aspx?id=ca7b3fe9-2b21-433a-919d-c232fe4ad361</feedburner:origLink></item>
    <item>
      <title>Verify JavaScript syntax using C#</title>
      <description>&lt;p&gt;In the past few days, I&amp;rsquo;ve worked on finding a way to do static code analysis on JavaScript files.The resaon is that I want to apply some sort of binary and source code checking like FxCop and StyleCop provides for C#.&lt;/p&gt;
&lt;p&gt;There exist some tools for linting JavaScript like &lt;a href="http://www.javascriptlint.com/"&gt;JavaScript Lint&lt;/a&gt;, but linting only checks syntax and not implementation. To do that I found the Jscript compiler build into the .NET Framework to be just what I wanted. It compiles JavaScript and reports if it finds any errors.&lt;/p&gt;
&lt;p&gt;To test it out, I wrote a simple C# class that takes an array of JavaScript files to compile. I then called the class from a unit test, so I could make the test fail if the compiler finds any errors with the script files. The class contains a single public method called &lt;em&gt;Compile&lt;/em&gt; and here is a simplified example on how to use it from any unit testing framework. You can download the class at the bottom of this post.&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;pre style="margin: 0px;"&gt;&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;&lt;p style="margin: 0px;"&gt;[&lt;span style="color: #2b91af;"&gt;Test&lt;/span&gt;]&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; JavascriptTest()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt;[] javascriptFiles = &lt;span style="color: #2b91af;"&gt;Directory&lt;/span&gt;.GetFiles(&lt;span style="color: #a31515;"&gt;@"D:\Website"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"*.js"&lt;/span&gt;, &lt;br /&gt;&lt;span style="color: #2b91af;"&gt;    SearchOption&lt;/span&gt;.AllDirectories);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;JavaScriptCompiler&lt;/span&gt; compiler = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;JavaScriptCompiler&lt;/span&gt;())&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp; &amp;nbsp; compiler.Compile(javascriptFiles);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color: #2b91af;"&gt;Assert&lt;/span&gt;.IsFalse(compiler.HasErrors, compiler.ErrorMessage);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;What&amp;rsquo;s nice is that by doing compile time checking of JavaScripts, I get that extra little security that&amp;rsquo;s so hard to get when developing JavaScript heavy websites. The Microsoft JScript compiler isn&amp;rsquo;t perfect, so I still recommend using a linting tool as well. The two approaches cover different scenarios.&amp;nbsp;I hope to have a very simple implementation on using a linting tool soon.&lt;/p&gt;
&lt;h2&gt;Download&lt;/h2&gt;
&lt;p&gt;Remember to add a reference to Microsoft.JScript in your Visual Studio project before using this class.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://madskristensen.net/file.axd?file=2009%2f10%2fJavaScriptCompiler.cs"&gt;JavaScriptCompiler.cs (2,48 kb)&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/bKOXzp0Hqf4/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/Verify-JavaScript-syntax-using-C.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=6f6b99df-d9aa-4af5-b2d7-71dd926063c9</guid>
      <pubDate>Wed, 28 Oct 2009 17:10:00 -0500</pubDate>
      <category>Client-side</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=6f6b99df-d9aa-4af5-b2d7-71dd926063c9</pingback:target>
      <slash:comments>15</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=6f6b99df-d9aa-4af5-b2d7-71dd926063c9</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/Verify-JavaScript-syntax-using-C.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=6f6b99df-d9aa-4af5-b2d7-71dd926063c9</wfw:commentRss>
    <enclosure url="http://madskristensen.net/file.axd?file=2009%2f10%2fJavaScriptCompiler.cs" length="2540" type="application/octet-stream" /><feedburner:origLink>http://madskristensen.net/post.aspx?id=6f6b99df-d9aa-4af5-b2d7-71dd926063c9</feedburner:origLink></item>
    <item>
      <title>Meta-tag bypasses IE8 checks</title>
      <description>&lt;p&gt;Internet Explorer 8 introduced a new mechanism for ensuring backwards compatibility with websites built for IE7, so "the web" didn't break with IE8's more standards compliant rendering. You could tell IE8 to render your website as IE7 and therefore avoid having to fix potential problems with markup or stylesheets. You can do that in two different ways:&lt;/p&gt;
&lt;p&gt;Using a meta-tag:&lt;br /&gt;&lt;em&gt;&amp;lt;meta http-equiv="X-UA-Compatible" content="IE=7" /&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;or this HTTP header:&lt;br /&gt;&lt;em&gt;X-UA-Compatible: IE=7&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This puts IE8 into IE7 rendering mode. You can read more about how and why this was done and made into a standard at &lt;a href="http://www.alistapart.com/articles/beyonddoctype"&gt;A List Apart&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The bonus feature&lt;/h2&gt;
&lt;p&gt;When IE8 renders a page, it looks for the meta tag or HTTP header in order to determine&amp;nbsp; whether or&amp;nbsp; not to render in regular standards mode or IE7 standards mode. So you would think that if you don't add the meta-tag or HTTP header, IE8 will just automatically render in IE8 standards mode, right?&lt;/p&gt;
&lt;p&gt;According to this &lt;a href="http://hsivonen.iki.fi/doctype/ie8-mode.png"&gt;flow diagram on IE8 rendering&lt;/a&gt;, this isn't the case. If you don't specify any meta-tag or HTTP-header, IE8 will go through a lot of checks in order to determine how to render your webpage. You can very easily avoid the overhead and uncertainty by specifying to always use IE8 rendering mode.&amp;nbsp; The diagram tells us to use the meta-tag to specify this directly:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;lt;meta http-equiv="X-UA-Compatible" content="IE=8" /&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This meta-tag tells IE8 to skip directly to the DOCTYPE check by bypassing all other checks. If you can't add the meta-tag but can add an HTTP header, use this:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;X-UA-Compatible: IE=8&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The diagram tells us that the meta-tag is preferable over the HTTP header.&lt;/p&gt;
&lt;h2&gt;Always target the latest IE browser&lt;/h2&gt;
&lt;p&gt;Setting the &lt;em&gt;X-UA-Compatible&lt;/em&gt; meta-tag/header to &lt;em&gt;IE=8&lt;/em&gt; only targets IE8 and no other browser. But what happens when IE9 ships? Microsoft has been clever enough to support the latest IE browser no matter what version might be. You can set &lt;em&gt;X-UA-Compatible&lt;/em&gt; to &lt;em&gt;IE=Edge&lt;/em&gt; and it will have effect on IE8 and all future IE versions. Keep in mind that upcoming beta releases and internal builds might not renders correctly, so use the &lt;em&gt;IE=Edge&lt;/em&gt; at your own risk.&lt;/p&gt;
&lt;h2&gt;Button disappears&lt;/h2&gt;
&lt;p&gt;Another nice thing about directly specifying IE8 rendering mode is that the &lt;em&gt;Compatibility View&lt;/em&gt; button disappears from the toolbar. Removing that choice might tell some visitors that what they are seeing is actually how you meant for your webpage to look.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://madskristensen.net/image.axd?picture=2009%2f9%2fcompatibilitymode.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;This is one of those little features that gives you a little extra control without compromising anything. I see no reason not to use this on any IE8 standards compliant website today.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/wTHVwObgzWk/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/Meta-tag-bypasses-IE8-checks.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=236144a6-0624-4e0e-bc52-325c31d86954</guid>
      <pubDate>Mon, 28 Sep 2009 13:22:00 -0500</pubDate>
      <category>Client-side</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=236144a6-0624-4e0e-bc52-325c31d86954</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=236144a6-0624-4e0e-bc52-325c31d86954</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/Meta-tag-bypasses-IE8-checks.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=236144a6-0624-4e0e-bc52-325c31d86954</wfw:commentRss>
    <feedburner:origLink>http://madskristensen.net/post.aspx?id=236144a6-0624-4e0e-bc52-325c31d86954</feedburner:origLink></item>
    <item>
      <title>Scale in the browser</title>
      <description>&lt;p&gt;Last week a colleague and I gave a talk about scalable architecture and where my colleague talked about databases and application layer scaling, I talked about scaling websites. More precisely, we talked about the &lt;a href="http://www.guardian.co.uk/business/2009/sep/20/vodafonegroup-telecoms"&gt;upcoming ZYB/Vodafone project&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Since there&amp;rsquo;s still a lot of secrecy about the project, we managed to keep the concepts general. General or not, I&amp;rsquo;d like to share some thoughts on a different way of scaling websites.&lt;/p&gt;
&lt;h2&gt;Load balancing&lt;/h2&gt;
&lt;p&gt;Larger websites are often hosted on multiple web servers under a &lt;a href="http://en.wikipedia.org/wiki/Load_balancing_%28computing%29"&gt;load balancer&lt;/a&gt; that distributes the requests evenly among the servers. This is an old technique for scaling out websites and has been widely used as the &lt;em&gt;de facto&lt;/em&gt; scaling mechanism for years.&amp;nbsp; It&amp;rsquo;s good, it works and it&amp;rsquo;s cheap. It&amp;rsquo;s cheap because web servers often don&amp;rsquo;t have to be the biggest machines in contrast to e.g. database servers.&lt;/p&gt;
&lt;p&gt;So, a load balanced web server&amp;nbsp;setup provides good and cheap scaling possibilities.&lt;/p&gt;
&lt;h2&gt;Reversed load balancing&lt;/h2&gt;
&lt;p&gt;Any website, load balanced or not, can also&amp;nbsp;use the vast untapped resources in the visitor&amp;rsquo;s browsers.&amp;nbsp;Think about it. Quad core CPU&amp;rsquo;s and 4GB memory is almost standard today &amp;ndash; even on laptops. Why not utilize the machine power behind the browsers to do some of the scaling for us?&lt;/p&gt;
&lt;p&gt;Traditionally, this is done using browser plug-ins like applets, Flash and Silverlight, but many more sites use JavaScript. Modern browsers process JavaScript very fast and efficient which makes it possible to use JavaScript for scaling purposes.&lt;/p&gt;
&lt;p&gt;To utilize the browsers memory we can cache data in JavaScript so we can eliminate chatty communication with the web server. An example would be to load all the data needed behind the scenes after the page is loaded and store it in JavaScript variables.&amp;nbsp; To utilize the CPU we can make calculations, dynamic rendering and other logic in JavaScript as well.&lt;/p&gt;
&lt;p&gt;By pushing some of the load to the browser we are able to scale even more than just using regular load balancing.&lt;/p&gt;
&lt;h2&gt;It&amp;rsquo;s not for everyone&lt;/h2&gt;
&lt;p&gt;There are some problems with this approach that makes it a bad choice for some websites. If enough of the visitors are using old browsers like IE6 then they will get a worse experience because JavaScript runs too slow. There&amp;rsquo;s also the case where a website just doesn&amp;rsquo;t have any data to cache like a personal website.&lt;/p&gt;
&lt;p&gt;For other types of websites it makes perfect sense. If your visitors have modern browsers and your website is heavily data driven, then it&amp;rsquo;s a possible candidate. The tests we have done at ZYB shows huge benefits by loading data behind the scenes - both the performance and scalability improves significantly. The load on the web servers dropped drastically with this technique. I hope to be able to show you some real numbers later.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/YWG60GEpK8o/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/Scale-in-the-browser.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=ec69e0ad-bc95-4d5a-aca1-52ac25982fc5</guid>
      <pubDate>Mon, 21 Sep 2009 14:17:00 -0500</pubDate>
      <category>ASP.NET</category>
      <category>Client-side</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=ec69e0ad-bc95-4d5a-aca1-52ac25982fc5</pingback:target>
      <slash:comments>7</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=ec69e0ad-bc95-4d5a-aca1-52ac25982fc5</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/Scale-in-the-browser.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=ec69e0ad-bc95-4d5a-aca1-52ac25982fc5</wfw:commentRss>
    <feedburner:origLink>http://madskristensen.net/post.aspx?id=ec69e0ad-bc95-4d5a-aca1-52ac25982fc5</feedburner:origLink></item>
    <item>
      <title>Iframe cross domain JavaScript calls</title>
      <description>&lt;p&gt;At &lt;a href="http://zyb.com"&gt;ZYB&lt;/a&gt; we have been doing cross domain JavaScript calls for quite some time now. Whenever we tell that to people, many don&amp;rsquo;t believe it is possible with standard security settings in any modern browser. This surprised me a bit since it has always been possible with a simple little trick.&lt;/p&gt;
&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;Say you have a website (site A) with an iframe wherein you host another website (site B). In old and unsecure browsers it was possible to do a JavaScript call from site B to site A like this:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;window.parent.doSomething();&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here the &lt;em&gt;doSomething&lt;/em&gt; function is living on site A and is called by site B through its parent window. For security reasons, this simple way of cross iframe communication was disabled years ago by all browser vendors.&lt;/p&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;There are&amp;nbsp;different scenarios with possible solutions:&lt;/p&gt;
&lt;h3&gt;1: Site B is a sub domain under/beside Site A&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s say that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Site A is located at &lt;em&gt;example.com&lt;/em&gt; or &lt;em&gt;sitea.example.com&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Site B is located at &lt;em&gt;siteb.example.com&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All you need to do is to add this line of JavaScript to both site A and B:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;document.domain = 'example.com'&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That tells the browser that both site A and B belongs to the app located at example.com and are therefore allowed to communicate using JavaScript. It could be by calling &lt;em&gt;window.parent.doSomething();&lt;/em&gt;&amp;nbsp;Now &lt;a href="http://en.wikipedia.org/wiki/Same_origin_policy"&gt;Same Origin Policy&lt;/a&gt; principle has been enabled on both sites.&lt;/p&gt;
&lt;h3&gt;2: Site B is on a different top domain than site A&lt;/h3&gt;
&lt;p&gt;This is more tricky, because we need to let the browser think both site A and B are under the same top domain.&amp;nbsp; When it does, we can implement the trick from solution 1 above.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s say that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Site A is located at &lt;em&gt;example.com&lt;/em&gt; or &lt;em&gt;sitea.example.com&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Site B is located at &lt;em&gt;foobar.com&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To make this work, you need to create a sub domain called e.g. &lt;em&gt;siteb.example.com&lt;/em&gt;. Then point the new sub domain to the IP address of &lt;em&gt;foobar.com&lt;/em&gt;. Now both site A and B is located under &lt;em&gt;example.com&lt;/em&gt; and you can start to implement solution 1.&lt;/p&gt;
&lt;p&gt;There is no security risk going on here because you can only implement solution 1 if both site A and B participate in the trick.&lt;/p&gt;
&lt;h3&gt;Other solutions&lt;/h3&gt;
&lt;p&gt;If you can't use either solution 1 or 2 the game isn't over. Here are some other techniques to use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html"&gt;JSONP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.blanquera.com/2009/03/iframe-proxy-natively-and-with-jquery.html"&gt;Iframe proxying&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Though not as simple as the document.domain trick, these are well documented and proven techniques.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/B4NUcB_vbnQ/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/Iframe-cross-domain-JavaScript-calls.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=1671c065-28aa-4f4e-b9cd-4bb104e247e8</guid>
      <pubDate>Tue, 25 Aug 2009 15:26:00 -0500</pubDate>
      <category>Client-side</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=1671c065-28aa-4f4e-b9cd-4bb104e247e8</pingback:target>
      <slash:comments>14</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=1671c065-28aa-4f4e-b9cd-4bb104e247e8</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/Iframe-cross-domain-JavaScript-calls.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=1671c065-28aa-4f4e-b9cd-4bb104e247e8</wfw:commentRss>
    <feedburner:origLink>http://madskristensen.net/post.aspx?id=1671c065-28aa-4f4e-b9cd-4bb104e247e8</feedburner:origLink></item>
    <item>
      <title>Off topic: The grand plan for 2009 follow up</title>
      <description>&lt;p&gt;Back in March, I wrote about &lt;a href="http://madskristensen.net/post/Off-topic-The-grand-plan-of-2009.aspx"&gt;my grand plan for 2009&lt;/a&gt; &amp;ndash; my new year&amp;rsquo;s resolution. The plan was simple. I had to visit 12 different countries in 2009, preferably 12 countries I&amp;rsquo;d never visited before. Now, half way through the year it&amp;rsquo;s time to do status on the progress.&lt;/p&gt;
&lt;h2&gt;January&lt;/h2&gt;
&lt;p&gt;A business trip to &lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=da&amp;amp;geocode=&amp;amp;q=D%C3%BCsseldorf,+Tyskland&amp;amp;sll=37.0625,-95.677068&amp;amp;sspn=42.631141,93.076172&amp;amp;ie=UTF8&amp;amp;split=0&amp;amp;ll=50.875311,6.767578&amp;amp;spn=17.079723,46.538086&amp;amp;t=h&amp;amp;z=5&amp;amp;iwloc=A"&gt;D&amp;uuml;sseldorf, Germany&lt;/a&gt; kicked off the plan. Beautiful city with very nice restaurants, bars and more Porche&amp;rsquo;s, Mercedes&amp;rsquo; and BMW&amp;rsquo;s I&amp;rsquo;ve ever seen in one place.&lt;/p&gt;
&lt;h2&gt;February&lt;/h2&gt;
&lt;p&gt;Another business trip, this time to rainy London. Also, later the same month I went to &lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=da&amp;amp;geocode=&amp;amp;q=chisinau,+Moldova&amp;amp;sll=47.411631,28.369885&amp;amp;sspn=18.301715,46.538086&amp;amp;ie=UTF8&amp;amp;ll=48.166085,26.411133&amp;amp;spn=18.037786,46.538086&amp;amp;t=h&amp;amp;z=5&amp;amp;iwloc=A"&gt;Chişinău, the capital of Moldova&lt;/a&gt;. This is by far the most interesting place I&amp;rsquo;ve ever visited and I have a feeling that I might be the first tourist in that country. I can highly recommend visiting Moldova and I will definitely go back in maybe 5 years time.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://madskristensen.net/image.axd?picture=2009%2f7%2fmoldova.jpg" alt="Moldova" /&gt;&lt;/p&gt;
&lt;h2&gt;March&lt;/h2&gt;
&lt;p&gt;Went to the MVP Summit in Seattle. It was my first time in the state of Washington, but my 5th trip to USA and my 14th state. It rained, but it didn&amp;rsquo;t change the fact that Seattle is a very nice city with very nice and outgoing people.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://madskristensen.net/image.axd?picture=2009%2f7%2fseatlle.jpg" alt="The Space Needle" /&gt;&lt;/p&gt;
&lt;h2&gt;April&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=da&amp;amp;geocode=&amp;amp;q=malaga,+spain&amp;amp;sll=39.622615,19.929199&amp;amp;sspn=10.402879,23.269043&amp;amp;ie=UTF8&amp;amp;ll=36.721274,-4.416504&amp;amp;spn=5.414566,11.634521&amp;amp;t=h&amp;amp;z=7&amp;amp;iwloc=A"&gt;Malaga, Spain&lt;/a&gt; was the starting point of my Easter holiday. From there we drove to &lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=da&amp;amp;geocode=&amp;amp;q=gibraltar,+gibraltar&amp;amp;sll=36.137741,-5.345374&amp;amp;sspn=1.364122,2.90863&amp;amp;ie=UTF8&amp;amp;ll=36.146747,-5.350342&amp;amp;spn=5.454737,11.634521&amp;amp;t=h&amp;amp;z=7&amp;amp;iwloc=A"&gt;Gibraltar&lt;/a&gt; to see the wild monkeys and beautiful views and of course the new casino. You can actually see&amp;nbsp;Morocco from there across the Mediterranean Sea. Then drove to Sevilla before returning home.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://madskristensen.net/image.axd?picture=2009%2f7%2fgibraltar.jpg" alt="Gibraltar" /&gt;&lt;/p&gt;
&lt;h2&gt;May&lt;/h2&gt;
&lt;p&gt;Visiting a friend in &lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=da&amp;amp;geocode=&amp;amp;q=stirling,+scotland&amp;amp;sll=35.906849,-6.273193&amp;amp;sspn=5.471349,11.634521&amp;amp;ie=UTF8&amp;amp;ll=56.12106,-3.955078&amp;amp;spn=15.112565,46.538086&amp;amp;t=h&amp;amp;z=5&amp;amp;iwloc=A"&gt;Stirling, Scotland&lt;/a&gt;, the home of &lt;a href="http://www.google.dk/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=2&amp;amp;url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FWilliam_Wallace&amp;amp;ei=DiBuSp2CPI3A-Qb-q_mLCw&amp;amp;usg=AFQjCNHFeWCC0L2A9zaESvBMTQFW14-axQ&amp;amp;sig2=WE99rYIcV8nA_fNv1OlkYw"&gt;William Wallace&lt;/a&gt; aka Mel Gibson in Braveheart. Drove around Loch Lomond and tried some excellent whisky along the way &amp;ndash; I wasn&amp;rsquo;t driving. I then took a flight from Scotland to D&amp;uuml;sseldorf to revisit the Vodafone mother ship before returning home.&lt;/p&gt;
&lt;h2&gt;June&lt;/h2&gt;
&lt;p&gt;Back in March I asked around the office if anyone wanted to join me on a trip to Amsterdam, Holland. 9 colleagues said &amp;ldquo;yes, please&amp;rdquo;, so off we went to one of the more fun places I&amp;rsquo;ve ever visited for reasons I will not share with you or anyone else. If you&amp;rsquo;ve been there you know why. If you haven&amp;rsquo;t been there, go before it&amp;rsquo;s too late.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://madskristensen.net/image.axd?picture=2009%2f7%2famsterdam.jpg" alt="Arriving in Amsterdam" /&gt;&lt;/p&gt;
&lt;h2&gt;June/July&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been very busy at work and by travelling, so for the summer holiday I just wanted to relax by a pool somewhere warm. I did that on &lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=da&amp;amp;geocode=&amp;amp;q=corfu,+greece&amp;amp;sll=56.12106,-3.955078&amp;amp;sspn=15.112565,46.538086&amp;amp;ie=UTF8&amp;amp;ll=39.622615,19.929199&amp;amp;spn=10.402879,23.269043&amp;amp;t=h&amp;amp;z=6&amp;amp;iwloc=A"&gt;Corfu&lt;/a&gt; &amp;ndash; a Greek island off of the Albanian coast. The only energy spent on that trip was getting into a cap to the ferry leaving for Sarande, Albania.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://madskristensen.net/image.axd?picture=2009%2f7%2fgreece.jpg" alt="Paradise Hotel in Corfu, Greece" /&gt;&lt;/p&gt;
&lt;p&gt;That concludes the first half of my grand plan. Next up is:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;August&lt;/strong&gt;: Fringe Festival in Edinburgh, Scotland and a trip to Boston&lt;br /&gt;&lt;strong&gt;September&lt;/strong&gt;: Weekend in Monaco to win big on the casinos&lt;br /&gt;&lt;strong&gt;October&lt;/strong&gt;: 11 days roundtrip to Iran&lt;/p&gt;
&lt;p&gt;After that it&amp;rsquo;s either India with the family in November or Malta for Christmas. If the rest of the year turns out as stated here, then the grand plan succeeds. This grand plan also carries some of the blame for me not blogging much anymore.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/VaMH_7s96F8/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/Off-topic-The-grand-plan-for-2009-follow-up.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=645fea36-e492-4930-a7e3-a76d9d94f83f</guid>
      <pubDate>Mon, 27 Jul 2009 17:29:00 -0500</pubDate>
      <category>Random thoughts</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=645fea36-e492-4930-a7e3-a76d9d94f83f</pingback:target>
      <slash:comments>7</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=645fea36-e492-4930-a7e3-a76d9d94f83f</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/Off-topic-The-grand-plan-for-2009-follow-up.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=645fea36-e492-4930-a7e3-a76d9d94f83f</wfw:commentRss>
    <feedburner:origLink>http://madskristensen.net/post.aspx?id=645fea36-e492-4930-a7e3-a76d9d94f83f</feedburner:origLink></item>
    <item>
      <title>Get last-modified header from response in ASP.NET</title>
      <description>&lt;p&gt;I&amp;rsquo;ve been working lately with some ASP.NET performance optimization automation HTTP modules. In one of them I needed to know if the last-modified header had been set through the &lt;em&gt;Response.Cache.SetLastModified(DateTime)&lt;/em&gt; method. For some reason, there is no API available anywhere within the BCL to retrieve the last modified date of a response &amp;ndash; you can only set it.&lt;/p&gt;
&lt;p&gt;Since the module wouldn&amp;rsquo;t work without a way to read the last modified date of the response, I had to use &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt; to figure out how to pull the information out using reflection. The result became a simple little method to retrieve the date. It looks like this:&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt; ReadLastModifiedFromResponse(&lt;span style="color: #2b91af;"&gt;HttpCachePolicy&lt;/span&gt; cache)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;BindingFlags&lt;/span&gt; flags = &lt;span style="color: #2b91af;"&gt;BindingFlags&lt;/span&gt;.NonPublic | &lt;span style="color: #2b91af;"&gt;BindingFlags&lt;/span&gt;.GetField | &lt;span style="color: #2b91af;"&gt;BindingFlags&lt;/span&gt;.Instance;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; (&lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;)cache.GetType().GetField(&lt;span style="color: #a31515;"&gt;"_utcLastModified"&lt;/span&gt;, flags).GetValue(cache);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;And you can use it like this:&lt;/p&gt;
&lt;div style="font-family: Courier New; background: white; color: black; font-size: 10pt;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt; responseModified = ReadLastModifiedFromResponse(Response.Cache);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; (responseModified &amp;gt; &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.MinValue)&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&amp;nbsp; &lt;span style="color: green;"&gt;// Last-modified is set. Do something...&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;If you know of another way to retrieving the last-modified date, please let me know.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/h7reZlrZVv8/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/Get-last-modified-header-from-response-in-ASPNET.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=d80a9d4d-f977-4693-a70a-bcb766fc2b74</guid>
      <pubDate>Thu, 21 May 2009 12:30:00 -0500</pubDate>
      <category>ASP.NET</category>
      <category>Tips and tricks</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=d80a9d4d-f977-4693-a70a-bcb766fc2b74</pingback:target>
      <slash:comments>14</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=d80a9d4d-f977-4693-a70a-bcb766fc2b74</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/Get-last-modified-header-from-response-in-ASPNET.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=d80a9d4d-f977-4693-a70a-bcb766fc2b74</wfw:commentRss>
    <feedburner:origLink>http://madskristensen.net/post.aspx?id=d80a9d4d-f977-4693-a70a-bcb766fc2b74</feedburner:origLink></item>
    <item>
      <title>ASP.NET developer categories</title>
      <description>&lt;p&gt;In the past 6 months I’ve been involved in hiring a lot of ASP.NET developers. It was very interesting to learn just how different skill sets ASP.NET developers have. It also made it more and more clear that every developer we talked to would fit into one of three categories: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The web developer &lt;/li&gt;    &lt;li&gt;The developer who build websites &lt;/li&gt;    &lt;li&gt;The ASP.NET super hero &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Before looking deeper into the different categories I recommend you too check out &lt;a href="http://madskristensen.net/post/ASPNET-is-a-database-framework.aspx"&gt;how I define the ASP.NET framework&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;The developer categories&lt;/h2&gt;  &lt;p&gt;With the ASP.NET definition in place it is now easier to look at the different categories of ASP.NET developers we have interviewed.&lt;/p&gt;  &lt;h3&gt;The web developer&lt;/h3&gt;  &lt;p&gt;Not many ASP.NET developers fall into this category. It’s usually the ones that come from classic ASP or PHP and made the switch to ASP.NET later on. They know everything about browser compatibility, JavaScript, CSS and the request life cycle. Also, they are usually not that hardcore in C# because they have mostly worked with client technologies. They are also more agnostic to the server-side platform and can work on PHP and RoR projects just as efficiently.&lt;/p&gt;  &lt;p&gt;The web developer is also the kind of guy who thinks about new web technologies such as &lt;a href="http://microformats.org"&gt;microformats&lt;/a&gt; and &lt;a href="http://openid.net"&gt;OpenID&lt;/a&gt;. This guy lives and breathes web.&lt;/p&gt;  &lt;h3&gt;The developer who builds websites&lt;/h3&gt;  &lt;p&gt;This is by far the biggest category. We’ve interviewed many developers who have worked with ASP.NET since it was first released. They have worked with everything from the database, data- and business logic, web services and ASP.NET. Most of them don’t care much for browser capabilities or JavaScript but they are hardcore C# developers. They have built many ASP.NET sites, but they are far from experts on the framework and stuff like modules and handlers are not where they have spent most of their time to say the least.&lt;/p&gt;  &lt;p&gt;Their knowledge of the .NET framework, BCL and C# is immense, but they don’t qualify as web developers. They don’t live and breathe web, but their skills are just as needed in an ASP.NET project.&lt;/p&gt;  &lt;p&gt;Take a web developer and a developer who build websites and put them in a room at the Romance Inn and wait 9 months. Then you get: &lt;/p&gt;  &lt;h3&gt;The ASP.NET super hero&lt;/h3&gt;  &lt;p&gt;This breed of developers is very difficult to get your hands on. They are a special race of individuals who know all about the ASP.NET framework and client-side technologies and are just as proficient in the more hardcore C# disciplines as well. ASP.NET is a very broad and diverse area because it is the point where the BCL, C#, XHTML, CSS, JavaScript, dependency injection, unit testing, mocking, AJAX etc. all come together in one project. To master all these disciplines takes an ASP.NET super hero.&lt;/p&gt;  &lt;p&gt;The web developer and the developer who builds websites are both very important to a successful execution of a website project, but at least one ASP.NET super hero is essential in my opinion.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/EgWv5VYs908/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/ASPNET-developer-categories.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=a71778ee-ea52-41ba-b3e3-0ce093b3284f</guid>
      <pubDate>Sun, 19 Apr 2009 15:51:43 -0500</pubDate>
      <category>ASP.NET</category>
      <category>Random thoughts</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=a71778ee-ea52-41ba-b3e3-0ce093b3284f</pingback:target>
      <slash:comments>20</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=a71778ee-ea52-41ba-b3e3-0ce093b3284f</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/ASPNET-developer-categories.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=a71778ee-ea52-41ba-b3e3-0ce093b3284f</wfw:commentRss>
    <feedburner:origLink>http://madskristensen.net/post.aspx?id=a71778ee-ea52-41ba-b3e3-0ce093b3284f</feedburner:origLink></item>
    <item>
      <title>ASP.NET is a database framework</title>
      <description>&lt;p&gt;I have a very clear view on what ASP.NET is and what it isn’t. I’ve never given it much thought until recently when I learned that my view was different from a lot of other ASP.NET developers’. It started at an ASP.NET session at the MVP summit where a presenter asked whether or not people in the audience used the Entity Framework or Linq2Sql. I thought to myself that data access had absolutely nothing to do with ASP.NET but found to my surprise I was the only one finding it a weird question at an ASP.NET session.&lt;/p&gt;  &lt;p&gt;Since that session I started talking to people about this and almost everyone told me that a website without some sort of database is a thing of the past and that being an ASP.NET developer involved mastering databases, data access and business logic. I don’t disagree that mastering these disciplines is a huge part of being a .NET developer, but I still refused that it had anything to do with ASP.NET. Yes, I’m that anal.&lt;/p&gt;  &lt;h2&gt;The field trip&lt;/h2&gt;  &lt;p&gt;So, I went to Barnes &amp;amp; Noble to find some ASP.NET books. They had 8 different titles and I started to look at the table of contents in all of them. 7 out of the 8 ASP.NET books had minimum one chapter about databases and data access. I looked at the covers again and was reassured that I was indeed skimming ASP.NET books. Not data access books, but ASP.NET books. &lt;/p&gt;  &lt;p&gt;What I have learned in the past few months is that databases and data access is part of ASP.NET. Or in other words, ASP.NET is a database presentation framework and NOT a web application framework. Not acceptable!&lt;/p&gt;  &lt;p&gt;Here is my view on what ASP.NET is and what it isn’t. &lt;/p&gt;  &lt;h2&gt;My clear view of ASP.NET&lt;/h2&gt;  &lt;p&gt;ASP.NET is a framework for creating dynamic websites. It is not a framework for doing data access, business logic or any other thing besides building websites. If your business logic knows it is being used by an ASP.NET project by relying on an HttpContext for instance, then you are doing something wrong. Business logic is an API for what ever (presentation) logic that sits on top of it whether it being ASP.NET, WinForms, WCF or something completely different. This is a rule of the &lt;a href="http://en.wikipedia.org/wiki/Multitier_architecture"&gt;N-tier application architecture&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Smaller web projects often have the business- and data logic classes in the App_Code folder within the web project itself. Those classes are physically part of the web project but logically they are separate from the ASP.NET logic and as such the same 3-tier architecture applies. But it is still not ASP.NET, it is just C# classes that physically lives inside the web project in Visual Studio.&lt;/p&gt;  &lt;p&gt;ASP.NET handles everything related to browser/server interactions and nothing more. Calling the database directly from your code-behind or controller action doesn’t make ADO.NET part of the ASP.NET framework. The presence of the BCL in both ASP.NET and the business logic makes it less transparent, but I hope you see my point.&lt;/p&gt;  &lt;p&gt;Even though the data- and business logic aspects are both related and important to ASP.NET developers, they are still not ASP.NET.&lt;/p&gt;  &lt;p&gt;This is my clear view on the &lt;strike&gt;ASP.NET&lt;/strike&gt; database presentation framework.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/netSlave/~3/TT4g4G55iYA/post.aspx</link>
      <author>Mads Kristensen</author>
      <comments>http://madskristensen.net/post/ASPNET-is-a-database-framework.aspx#comment</comments>
      <guid isPermaLink="false">http://madskristensen.net/post.aspx?id=443f291e-9b57-41ea-94d0-3da8d0197c4b</guid>
      <pubDate>Sun, 19 Apr 2009 15:34:29 -0500</pubDate>
      <category>ASP.NET</category>
      <dc:publisher>Mads Kristensen</dc:publisher>
      <pingback:server>http://madskristensen.net/pingback.axd</pingback:server>
      <pingback:target>http://madskristensen.net/post.aspx?id=443f291e-9b57-41ea-94d0-3da8d0197c4b</pingback:target>
      <slash:comments>21</slash:comments>
      <trackback:ping>http://madskristensen.net/trackback.axd?id=443f291e-9b57-41ea-94d0-3da8d0197c4b</trackback:ping>
      <wfw:comment>http://madskristensen.net/post/ASPNET-is-a-database-framework.aspx#comment</wfw:comment>
      <wfw:commentRss>http://madskristensen.net/syndication.axd?post=443f291e-9b57-41ea-94d0-3da8d0197c4b</wfw:commentRss>
    <feedburner:origLink>http://madskristensen.net/post.aspx?id=443f291e-9b57-41ea-94d0-3da8d0197c4b</feedburner:origLink></item>
  </channel>
</rss>
