<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 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:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>this.Pose() as Expert - ASP.NET</title>
    <link>http://chrison.net/</link>
    <description />
    <language>en-us</language>
    <copyright>Christoph Wille</copyright>
    <lastBuildDate>Fri, 08 Feb 2008 06:54:08 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>christoph.wille@gmail.com</managingEditor>
    <webMaster>christoph.wille@gmail.com</webMaster>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=cad71ee8-c091-4feb-8e4b-592bd6052ce8</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,cad71ee8-c091-4feb-8e4b-592bd6052ce8.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,cad71ee8-c091-4feb-8e4b-592bd6052ce8.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=cad71ee8-c091-4feb-8e4b-592bd6052ce8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Yesterday, we found ourselves at the receiving end of an attack against one of our
German Wikis that are running the <a href="http://www.screwturn.eu/">ScrewTurn</a> Wiki
software. Turns out that it was a security issue even with the then latest version
2.0.23. Dario Solera - the maintainer of ScrewTurn - acted real fast when I informed
him about the root cause of the attack and released v2.0.24 yesterday night. 
</p>
        <p>
Please <a href="http://www.screwturn.eu/download.ashx">download</a> and upgrade immediately!
The issue is being actively exploited (zero day if you so will).
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=cad71ee8-c091-4feb-8e4b-592bd6052ce8" />
      </body>
      <title>Important Security Fix for ScrewTurn</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,cad71ee8-c091-4feb-8e4b-592bd6052ce8.aspx</guid>
      <link>http://chrison.net/ImportantSecurityFixForScrewTurn.aspx</link>
      <pubDate>Fri, 08 Feb 2008 06:54:08 GMT</pubDate>
      <description>&lt;p&gt;
Yesterday, we found ourselves at the receiving end of an attack against one of our
German Wikis that are running the &lt;a href="http://www.screwturn.eu/"&gt;ScrewTurn&lt;/a&gt; Wiki
software. Turns out that it was a security issue even with the then latest version
2.0.23. Dario Solera - the maintainer of ScrewTurn - acted real fast when I informed
him about the root cause of the attack and released v2.0.24 yesterday night. 
&lt;/p&gt;
&lt;p&gt;
Please &lt;a href="http://www.screwturn.eu/download.ashx"&gt;download&lt;/a&gt; and upgrade immediately!
The issue is being actively exploited (zero day if you so will).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=cad71ee8-c091-4feb-8e4b-592bd6052ce8" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,cad71ee8-c091-4feb-8e4b-592bd6052ce8.aspx</comments>
      <category>ASP.NET</category>
      <category>Security</category>
      <category>this</category>
      <category>Use the source Luke</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=9fbb839e-8b5a-4739-9d68-2f50f22f9114</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,9fbb839e-8b5a-4739-9d68-2f50f22f9114.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,9fbb839e-8b5a-4739-9d68-2f50f22f9114.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=9fbb839e-8b5a-4739-9d68-2f50f22f9114</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is a bugfix release for the previously posted <a href="http://chrison.net/nGalleryUpdatedForASPNET20.aspx">port
of nGallery to ASP.NET 3.5</a>. The following changes are incorporated:
</p>
        <ul>
          <li>
Bugfix: slideshow had "photos/" hardcoded in nGalleryLib (for navigation buttons)</li>
          <li>
Bugfix: Event log exceptions, please see <a href="http://todotnet.com/archive/0001/01/01/7472.aspx">Get
GoogleBot to crash your .NET 2.0 site</a> (plus <a href="http://www.mattcutts.com/blog/asp-net-2-and-url-rewriting-sometimes-harmful/">ASP.NET
2 + url rewriting considered harmful in some cases</a>). <a href="http://blogs.developpeur.org/nix/">Nicolas
Sorel</a> was nice enough to provide me with his .browser definition files.</li>
          <li>
Bugfix: default_highlight_image.jpg no longer resided in /photos and therefore caused
an exception for galleries that had no highlighted image; moved it back to \photos</li>
          <li>
Change: AlbumHandler no longer implements IHttpHandler</li>
          <li>
Change: AssemblyInfo.cs changed version to 2.0 to differentiate from original 1.6.1</li>
        </ul>
        <p>
That's all the changes that happened, here are the source and deployment files:
</p>
        <p>
          <a href="http://chrison.net/content/binary/nGalleryTNG2_ProjectFiles.zip">nGalleryTNG2_ProjectFiles.zip
(2.95 MB)</a>
          <br />
          <a href="http://chrison.net/content/binary/nGalleryTNG2_WebFiles.zip">nGalleryTNG2_WebFiles.zip
(1.03 MB)</a>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=9fbb839e-8b5a-4739-9d68-2f50f22f9114" />
      </body>
      <title>nGallery TNG Update</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,9fbb839e-8b5a-4739-9d68-2f50f22f9114.aspx</guid>
      <link>http://chrison.net/nGalleryTNGUpdate.aspx</link>
      <pubDate>Thu, 13 Dec 2007 10:42:52 GMT</pubDate>
      <description>&lt;p&gt;
This is a bugfix release for the previously posted &lt;a href="http://chrison.net/nGalleryUpdatedForASPNET20.aspx"&gt;port
of nGallery to ASP.NET 3.5&lt;/a&gt;. The following changes are incorporated:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Bugfix: slideshow had "photos/" hardcoded in nGalleryLib (for navigation buttons)&lt;/li&gt;
&lt;li&gt;
Bugfix: Event log exceptions, please see&amp;nbsp;&lt;a href="http://todotnet.com/archive/0001/01/01/7472.aspx"&gt;Get
GoogleBot to crash your .NET 2.0 site&lt;/a&gt; (plus &lt;a href="http://www.mattcutts.com/blog/asp-net-2-and-url-rewriting-sometimes-harmful/"&gt;ASP.NET
2 + url rewriting considered harmful in some cases&lt;/a&gt;). &lt;a href="http://blogs.developpeur.org/nix/"&gt;Nicolas
Sorel&lt;/a&gt; was nice enough to provide me with his .browser definition files.&lt;/li&gt;
&lt;li&gt;
Bugfix: default_highlight_image.jpg no longer resided in /photos and therefore caused
an exception for galleries that had no highlighted image; moved it back to \photos&lt;/li&gt;
&lt;li&gt;
Change: AlbumHandler no longer implements IHttpHandler&lt;/li&gt;
&lt;li&gt;
Change: AssemblyInfo.cs changed version to 2.0 to differentiate from original 1.6.1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
That's all the changes that happened, here are the source and deployment files:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/nGalleryTNG2_ProjectFiles.zip"&gt;nGalleryTNG2_ProjectFiles.zip
(2.95 MB)&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://chrison.net/content/binary/nGalleryTNG2_WebFiles.zip"&gt;nGalleryTNG2_WebFiles.zip
(1.03 MB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=9fbb839e-8b5a-4739-9d68-2f50f22f9114" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,9fbb839e-8b5a-4739-9d68-2f50f22f9114.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Use the source Luke</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=d95e8950-a8c7-450f-a9db-4f22704ce70b</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,d95e8950-a8c7-450f-a9db-4f22704ce70b.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,d95e8950-a8c7-450f-a9db-4f22704ce70b.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=d95e8950-a8c7-450f-a9db-4f22704ce70b</wfw:commentRss>
      <slash:comments>11</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://chrison.net/nGalleryTNGUpdate.aspx">I have posted an updated version</a>
        </p>
        <p>
Given my plans to rather sooner than later upgrade my server to IIS7, I am currently
switching all applications to ASP.NET 2.0 in preparation of this move. But there was
nGallery, which I used all over the place when I needed a photo gallery...
</p>
        <p>
Today I decided it was about time to do something about it, and gave converting nGallery
to .NET 2.0 a try (actually all the projects target .NET Framework 3.5). Turns out
it took me roundabout two hours for this whole endeavour. To save everybody else time,
here is my VS2008 solution tree:
</p>
        <p>
          <a href="http://chrison.net/content/binary/nGalleryTNG.zip">nGalleryTNG.zip (2.92
MB)</a>
        </p>
        <p>
What is changed compared to the original nGallery 1.6.1 for ASP.NET 1.1? Here is a
somewhat complete laundry list:
</p>
        <ul>
          <li>
Converted it to a Web Application project 
</li>
          <li>
Placed all third party source code in the ThirdParty folder. That way I can always
change and recompile if necessary. 
</li>
          <li>
Took all static images from the \photos directories and put them into \images. No
more mixing the photo handler &amp; photo cache with the Web site's images. 
</li>
          <li>
The album handler is now being abused in Application_BeginRequest, plus it now uses
RewritePath. Fixes the darn Server.Transfer errors. 
</li>
          <li>
Moved the configuration of nGallery from the data folder to App_Data. Other than that:
no configuration changes.</li>
        </ul>
        <p>
I did not switch to ASP.NET 2.0 master pages, it still uses the old user control approach.
But after all, I only needed it in a working fashion for 2.0+.
</p>
        <p>
Note: I only tested the XML-based storage because that's how I use nGallery. The SQL-storage
has received no testing whatsoever!
</p>
        <p>
Download Web site files only: <a href="http://chrison.net/content/binary/nGalleryTNG_WebSite.zip">nGalleryTNG_WebSite.zip
(924.39 KB)</a></p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=d95e8950-a8c7-450f-a9db-4f22704ce70b" />
      </body>
      <title>nGallery Updated For ASP.NET 2.0</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,d95e8950-a8c7-450f-a9db-4f22704ce70b.aspx</guid>
      <link>http://chrison.net/nGalleryUpdatedForASPNET20.aspx</link>
      <pubDate>Fri, 30 Nov 2007 14:07:36 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://chrison.net/nGalleryTNGUpdate.aspx"&gt;I have posted an updated version&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Given my plans to rather sooner than later upgrade my server to IIS7, I am currently
switching all applications to ASP.NET 2.0 in preparation of this move. But there was
nGallery, which I used all over the place when I needed a photo gallery...
&lt;/p&gt;
&lt;p&gt;
Today I decided it was about time to do something about it, and gave converting nGallery
to .NET 2.0 a try (actually all the projects target .NET Framework 3.5). Turns out
it took me roundabout two hours for this whole endeavour. To save everybody else time,
here is my VS2008 solution tree:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/nGalleryTNG.zip"&gt;nGalleryTNG.zip (2.92
MB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
What is changed compared to the original nGallery 1.6.1 for ASP.NET 1.1? Here is a
somewhat complete laundry list:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Converted it to a Web Application project 
&lt;li&gt;
Placed all third party source code in the ThirdParty folder. That way I can always
change and recompile if necessary. 
&lt;li&gt;
Took all static images from the \photos directories and put them into \images. No
more mixing the photo handler &amp;amp; photo cache with the Web site's images. 
&lt;li&gt;
The album handler is now being abused in Application_BeginRequest, plus it now uses
RewritePath. Fixes the darn Server.Transfer errors. 
&lt;li&gt;
Moved the configuration of nGallery from the data folder to App_Data. Other than that:
no configuration changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I did not switch to ASP.NET 2.0 master pages, it still uses the old user control approach.
But after all, I only needed it in a working fashion for 2.0+.
&lt;/p&gt;
&lt;p&gt;
Note: I only tested the XML-based storage because that's how I use nGallery. The SQL-storage
has received no testing whatsoever!
&lt;/p&gt;
&lt;p&gt;
Download Web site files only: &lt;a href="http://chrison.net/content/binary/nGalleryTNG_WebSite.zip"&gt;nGalleryTNG_WebSite.zip
(924.39 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=d95e8950-a8c7-450f-a9db-4f22704ce70b" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,d95e8950-a8c7-450f-a9db-4f22704ce70b.aspx</comments>
      <category>2 Ohhhh</category>
      <category>3.5</category>
      <category>ASP.NET</category>
      <category>Use the source Luke</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=93b1e18f-b3ad-4371-b06b-6cd580f46b62</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,93b1e18f-b3ad-4371-b06b-6cd580f46b62.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,93b1e18f-b3ad-4371-b06b-6cd580f46b62.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=93b1e18f-b3ad-4371-b06b-6cd580f46b62</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I posted a version of the <a href="http://chrison.net/ReallySimpleGuestbookWithXLinq.aspx">Really
Simple Guestbook - With XLinq</a> for Orcas Beta 2 earlier on this blog. Today, I
updated this small application for VS2008 RTM. The following changes are incorporated:
</p>
        <ul>
          <li>
It is now a Web project, no longer file system based 
</li>
          <li>
It includes <a href="http://codeplex.com/aip">AIP</a> for form spam protection (aka
captcha)</li>
        </ul>
        <p>
I decided to not include the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=EFB9C819-53FF-4F82-BFAF-E11625130C25&amp;displaylang=en">Microsoft
Anti-Cross Site Scripting Library V1.5</a>, that is up to the reader if additional
security is required (note: you'd have to add this to AddEntry.aspx's logic of inserting
new guestbook entries).
</p>
        <p>
Download: <a href="http://chrison.net/content/binary/XlinqGuestbook.zip">XlinqGuestbook.zip
(165.53 KB)</a>, License: BSD
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=93b1e18f-b3ad-4371-b06b-6cd580f46b62" />
      </body>
      <title>Xlinq Guestbook for VS 2008 RTM</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,93b1e18f-b3ad-4371-b06b-6cd580f46b62.aspx</guid>
      <link>http://chrison.net/XlinqGuestbookForVS2008RTM.aspx</link>
      <pubDate>Fri, 30 Nov 2007 08:55:46 GMT</pubDate>
      <description>&lt;p&gt;
I posted a version of the&amp;nbsp;&lt;a href="http://chrison.net/ReallySimpleGuestbookWithXLinq.aspx"&gt;Really
Simple Guestbook - With XLinq&lt;/a&gt; for Orcas Beta 2 earlier on this blog. Today, I
updated this small application for VS2008 RTM. The following changes are incorporated:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
It is now a Web project, no longer file system based 
&lt;li&gt;
It includes &lt;a href="http://codeplex.com/aip"&gt;AIP&lt;/a&gt; for form spam protection (aka
captcha)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I decided&amp;nbsp;to not include&amp;nbsp;the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=EFB9C819-53FF-4F82-BFAF-E11625130C25&amp;amp;displaylang=en"&gt;Microsoft
Anti-Cross Site Scripting Library V1.5&lt;/a&gt;, that is up to the reader if additional
security is required (note: you'd have to add this to AddEntry.aspx's logic of inserting
new guestbook entries).
&lt;/p&gt;
&lt;p&gt;
Download: &lt;a href="http://chrison.net/content/binary/XlinqGuestbook.zip"&gt;XlinqGuestbook.zip
(165.53 KB)&lt;/a&gt;, License: BSD
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=93b1e18f-b3ad-4371-b06b-6cd580f46b62" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,93b1e18f-b3ad-4371-b06b-6cd580f46b62.aspx</comments>
      <category>.NET</category>
      <category>3.5</category>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=4dba1166-1d1f-4d5d-aa83-e98e58649987</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,4dba1166-1d1f-4d5d-aa83-e98e58649987.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,4dba1166-1d1f-4d5d-aa83-e98e58649987.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=4dba1166-1d1f-4d5d-aa83-e98e58649987</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>XSSDetect is a static code analysis tool that helps identify Cross-Site Scripting
security flaws found within Web applications. It is able to scan compiled managed
assemblies (C#, Visual Basic .NET, J#) and analyze dataflow paths from sources of
user-controlled input to vulnerable outputs. It also detects whether proper encoding
or filtering has been applied to the data and will ignore such "sanitized" paths.</em>
          <a href="http://www.microsoft.com/downloads/details.aspx?familyid=19A9E348-BDB9-45B3-A1B7-44CCDCB7CFBE&amp;displaylang=en">Download</a>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=4dba1166-1d1f-4d5d-aa83-e98e58649987" />
      </body>
      <title>XSS Detect Beta Code Analysis Tool</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,4dba1166-1d1f-4d5d-aa83-e98e58649987.aspx</guid>
      <link>http://chrison.net/XSSDetectBetaCodeAnalysisTool.aspx</link>
      <pubDate>Fri, 02 Nov 2007 11:51:21 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;XSSDetect is a static code analysis tool that helps identify Cross-Site Scripting
security flaws found within Web applications. It is able to scan compiled managed
assemblies (C#, Visual Basic .NET, J#) and analyze dataflow paths from sources of
user-controlled input to vulnerable outputs. It also detects whether proper encoding
or filtering has been applied to the data and will ignore such "sanitized" paths.&lt;/em&gt; &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=19A9E348-BDB9-45B3-A1B7-44CCDCB7CFBE&amp;amp;displaylang=en"&gt;Download&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=4dba1166-1d1f-4d5d-aa83-e98e58649987" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,4dba1166-1d1f-4d5d-aa83-e98e58649987.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Security</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=bc6dc56c-3054-4ba8-b976-3f4890d8ca15</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,bc6dc56c-3054-4ba8-b976-3f4890d8ca15.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,bc6dc56c-3054-4ba8-b976-3f4890d8ca15.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=bc6dc56c-3054-4ba8-b976-3f4890d8ca15</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Article at The Register: <a href="http://www.regdeveloper.co.uk/2007/10/30/asp_net_java_project_cool/">How
ASP.NET began in Java</a>. Reminds me of the "C# is COOL" t-shirt I have...
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=bc6dc56c-3054-4ba8-b976-3f4890d8ca15" />
      </body>
      <title>How ASP.NET began in Java</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,bc6dc56c-3054-4ba8-b976-3f4890d8ca15.aspx</guid>
      <link>http://chrison.net/HowASPNETBeganInJava.aspx</link>
      <pubDate>Tue, 30 Oct 2007 16:12:41 GMT</pubDate>
      <description>&lt;p&gt;
Article at The Register: &lt;a href="http://www.regdeveloper.co.uk/2007/10/30/asp_net_java_project_cool/"&gt;How
ASP.NET began in Java&lt;/a&gt;. Reminds me of the "C# is COOL" t-shirt I have...
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=bc6dc56c-3054-4ba8-b976-3f4890d8ca15" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,bc6dc56c-3054-4ba8-b976-3f4890d8ca15.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=25ec2ef9-d32e-40ac-a496-a79b16abaab7</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,25ec2ef9-d32e-40ac-a496-a79b16abaab7.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,25ec2ef9-d32e-40ac-a496-a79b16abaab7.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=25ec2ef9-d32e-40ac-a496-a79b16abaab7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Been on holidays, at conferences (eg last week Ask The Experts @ XTOPIA in Berlin),
and worked on various projects - a couple of reasons it was rather quiet lately in
this blog.
</p>
        <p>
Yesterday I decided I needed a simple guestbook application for a to-be-developed
private Web site, and because I didn't find anything that fit my needs I decided to
write one myself with the goal of (ab)using XLinq in the course of this endeavour:
</p>
        <p>
          <a href="http://chrison.net/content/binary/Guestbook_XLINQ.zip">Guestbook_XLINQ.zip
(7.09 KB)</a>
        </p>
        <p>
Caveat emptor: I am no designer (surprise!). But thanks to no design it should be
easy for you to add your own design. However, as <a href="http://msdn.microsoft.com/msdnmag/issues/07/09/">this
month's MSDN magazine is all about security</a>, I decided to make the application
production-ready security-wise. You'll find a lot of parsing plus XSRF protection
(note: this version does not check for integer overflow in calculating the start row).
</p>
        <p>
Missing features: this guestbook is not prepared for localization, nor does it use
a control-based approach (where you drop those in your pages and get an in-place guestbook).
</p>
        <p>
          <strong>Update</strong> a version of this application for VS2008 RTM is available <a href="http://chrison.net/XlinqGuestbookForVS2008RTM.aspx">here</a>.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=25ec2ef9-d32e-40ac-a496-a79b16abaab7" />
      </body>
      <title>Really Simple Guestbook - With XLinq</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,25ec2ef9-d32e-40ac-a496-a79b16abaab7.aspx</guid>
      <link>http://chrison.net/ReallySimpleGuestbookWithXLinq.aspx</link>
      <pubDate>Mon, 15 Oct 2007 07:56:36 GMT</pubDate>
      <description>&lt;p&gt;
Been on holidays, at conferences (eg last week Ask The Experts @ XTOPIA in Berlin),
and worked on various projects - a couple of reasons it was rather quiet lately in
this blog.
&lt;/p&gt;
&lt;p&gt;
Yesterday I decided&amp;nbsp;I needed a simple guestbook application for a to-be-developed
private Web site, and because I didn't find anything that fit my needs I decided to
write one myself with the goal of (ab)using XLinq in the course of this endeavour:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/Guestbook_XLINQ.zip"&gt;Guestbook_XLINQ.zip
(7.09 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Caveat emptor: I am no designer (surprise!). But thanks to no design it should be
easy for you to add your own design. However, as &lt;a href="http://msdn.microsoft.com/msdnmag/issues/07/09/"&gt;this
month's MSDN magazine is all about security&lt;/a&gt;, I decided to make the application
production-ready security-wise. You'll find a lot of parsing plus XSRF protection
(note: this version does not check for integer overflow in calculating the start row).
&lt;/p&gt;
&lt;p&gt;
Missing features: this guestbook is not prepared for localization, nor does it use
a control-based approach (where you drop those in your pages and get an in-place&amp;nbsp;guestbook).
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update&lt;/strong&gt; a version of this application for VS2008 RTM is available &lt;a href="http://chrison.net/XlinqGuestbookForVS2008RTM.aspx"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=25ec2ef9-d32e-40ac-a496-a79b16abaab7" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,25ec2ef9-d32e-40ac-a496-a79b16abaab7.aspx</comments>
      <category>3.5</category>
      <category>ASP.NET</category>
      <category>Security</category>
      <category>Use the source Luke</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=dc73ebd9-4171-45fc-b5cd-87b49aaa1d3a</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,dc73ebd9-4171-45fc-b5cd-87b49aaa1d3a.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,dc73ebd9-4171-45fc-b5cd-87b49aaa1d3a.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=dc73ebd9-4171-45fc-b5cd-87b49aaa1d3a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have been doing some sprucing up of SharpDevelop's Web offerings today - namely
the <a href="http://codeconverter.sharpdevelop.net/">code converter</a>. Up until
today, you only could convert syntactically valid classes. Recently, Daniel implemented
the <a href="http://laputa.sharpdevelop.net/NRefactorySnippetParser.aspx">SnippetParser</a> class,
which is now in use for the <a href="http://codeconverter.sharpdevelop.net/SnippetConverter.aspx">snippet
converter</a> (C# to VB.NET, VB.NET to C#). Note: the <a href="http://codeconverter.sharpdevelop.net/ConvertService.asmx">Web
service for code conversion</a> does support both class and snippet conversion, a <a href="http://codeconverter.sharpdevelop.net/DotNetClientApplication.aspx">Windows
client sample</a> is available for the former.
</p>
        <p>
Also new (just completed a few minutes ago) is the <a href="http://codeconverter.sharpdevelop.net/FormatCode.aspx">code
formatter</a>: it uses the highlighting engine from SharpDevelop's text editor to
HTML-ize a bunch of formats: ASP/XHTML, BAT, Boo, Coco, C++.NET, C#, HTML, Java, JavaScript,
Patch, PHP, TeX, VBNET, XML. Again, there is a Web service available, as well as a <a href="http://codeconverter.sharpdevelop.net/CodeFormatClient.aspx">sample
using the service</a>. This offering is built upon the HtmlSyntaxColorizer sample
that can be found in SharpDevelop revisions &gt; 2522 (currently only on the <a href="http://build.sharpdevelop.net/BuildArtefacts/">build
server</a>)
</p>
        <p>
I am sure that both the snippet converter as well as the code formatter are welcome
additions. Spread the word! After all, it's free.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=dc73ebd9-4171-45fc-b5cd-87b49aaa1d3a" />
      </body>
      <title>Code Conversion and Code Formatting News</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,dc73ebd9-4171-45fc-b5cd-87b49aaa1d3a.aspx</guid>
      <link>http://chrison.net/CodeConversionAndCodeFormattingNews.aspx</link>
      <pubDate>Thu, 24 May 2007 20:06:07 GMT</pubDate>
      <description>&lt;p&gt;
I have been doing some sprucing up of SharpDevelop's Web offerings today - namely
the &lt;a href="http://codeconverter.sharpdevelop.net/"&gt;code converter&lt;/a&gt;. Up until
today, you only could convert syntactically valid classes. Recently, Daniel implemented
the &lt;a href="http://laputa.sharpdevelop.net/NRefactorySnippetParser.aspx"&gt;SnippetParser&lt;/a&gt; class,
which is now in use for the &lt;a href="http://codeconverter.sharpdevelop.net/SnippetConverter.aspx"&gt;snippet
converter&lt;/a&gt; (C# to VB.NET, VB.NET to C#). Note: the &lt;a href="http://codeconverter.sharpdevelop.net/ConvertService.asmx"&gt;Web
service for code conversion&lt;/a&gt; does support both class and snippet conversion, a &lt;a href="http://codeconverter.sharpdevelop.net/DotNetClientApplication.aspx"&gt;Windows
client sample&lt;/a&gt; is available for the former.
&lt;/p&gt;
&lt;p&gt;
Also new (just completed a few minutes ago) is the &lt;a href="http://codeconverter.sharpdevelop.net/FormatCode.aspx"&gt;code
formatter&lt;/a&gt;: it uses the highlighting engine from SharpDevelop's text editor to
HTML-ize a bunch of formats: ASP/XHTML, BAT, Boo, Coco, C++.NET, C#, HTML, Java, JavaScript,
Patch, PHP, TeX, VBNET, XML. Again, there is a Web service available, as well as a &lt;a href="http://codeconverter.sharpdevelop.net/CodeFormatClient.aspx"&gt;sample
using the service&lt;/a&gt;. This offering is built upon the HtmlSyntaxColorizer sample
that can be found in SharpDevelop revisions &amp;gt; 2522 (currently only on the &lt;a href="http://build.sharpdevelop.net/BuildArtefacts/"&gt;build
server&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
I am sure that both the snippet converter as well as the code formatter are welcome
additions. Spread the word! After all, it's free.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=dc73ebd9-4171-45fc-b5cd-87b49aaa1d3a" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,dc73ebd9-4171-45fc-b5cd-87b49aaa1d3a.aspx</comments>
      <category>ASP.NET</category>
      <category>Cool Download</category>
      <category>this</category>
      <category>Use the source Luke</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=2e206d1c-b1ca-42e5-91c3-f3cb71bba2d7</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,2e206d1c-b1ca-42e5-91c3-f3cb71bba2d7.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,2e206d1c-b1ca-42e5-91c3-f3cb71bba2d7.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=2e206d1c-b1ca-42e5-91c3-f3cb71bba2d7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Bill Staples put together a post on <a href="http://blogs.iis.net/bills/archive/2007/04/25/what-s-new-in-iis7-beta-3.aspx">what's
new in IIS7 Beta 3</a>. He also talks about the all-new IIS7 FTP server (which I knew
about for a long time - I had hoped Beta 3 would be available for my MSDN Briefing
in Vienna last month, but no such luck). Also, he mentions the GoLive! license for
IIS7. 
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=2e206d1c-b1ca-42e5-91c3-f3cb71bba2d7" />
      </body>
      <title>What's New in IIS7 Beta 3?</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,2e206d1c-b1ca-42e5-91c3-f3cb71bba2d7.aspx</guid>
      <link>http://chrison.net/WhatsNewInIIS7Beta3.aspx</link>
      <pubDate>Thu, 26 Apr 2007 10:20:02 GMT</pubDate>
      <description>&lt;p&gt;
Bill Staples put together a post on &lt;a href="http://blogs.iis.net/bills/archive/2007/04/25/what-s-new-in-iis7-beta-3.aspx"&gt;what's
new in IIS7 Beta 3&lt;/a&gt;. He also talks about the all-new IIS7 FTP server (which I knew
about for a long time - I had hoped Beta 3 would be available for my MSDN Briefing
in Vienna last month, but no such luck). Also, he mentions the GoLive! license for
IIS7. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=2e206d1c-b1ca-42e5-91c3-f3cb71bba2d7" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,2e206d1c-b1ca-42e5-91c3-f3cb71bba2d7.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>IIS</category>
      <category>Longhorn</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=b14cf193-1f1f-44e1-b973-f1a7fbde8ddc</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,b14cf193-1f1f-44e1-b973-f1a7fbde8ddc.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,b14cf193-1f1f-44e1-b973-f1a7fbde8ddc.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=b14cf193-1f1f-44e1-b973-f1a7fbde8ddc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Nikhil has updated his controls for <a href="http://ajax.asp.net/">ASP.NET AJAX</a> 1.0. <a href="http://www.nikhilk.net/Entry.aspx?id=152">Download
here</a></p>
        <p>
Quote from his blog (so you know why you should go and download them):
</p>
        <ul>
          <li>
            <em>
              <strong>UpdateHistory</strong>This is a non-visual control that allows you to
add history entries to the browser's navigation stack selectively for some post-backs,
and not for some others. This helps fix the back button to make it work, and allows
you to implement Ajax patterns such as "logical navigation" and unique URLs.</em>
          </li>
          <li>
            <em>
              <strong>StyledUpdatePanel</strong> A simple derived UpdatePanel that adds
CSS class semantics. A simple addition, but a useful feature, nevertheless, that didn't
make the feature cut.</em>
          </li>
          <li>
            <em>
              <strong>AnimatedUpdatePanel</strong> Another derived UpdatePanel that displays
new content using a variety of animations or effects: slides, wipes, cross-fades as
well as a visual highlight. This allows you to implement the "visual notification"
Ajax patterns such as the one second spotlight and one second mutation.</em>
          </li>
        </ul>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=b14cf193-1f1f-44e1-b973-f1a7fbde8ddc" />
      </body>
      <title>UpdateControls: UpdateHistory and AnimatedUpdatePanel</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,b14cf193-1f1f-44e1-b973-f1a7fbde8ddc.aspx</guid>
      <link>http://chrison.net/UpdateControlsUpdateHistoryAndAnimatedUpdatePanel.aspx</link>
      <pubDate>Tue, 06 Feb 2007 11:59:52 GMT</pubDate>
      <description>&lt;p&gt;
Nikhil has updated his controls for &lt;a href="http://ajax.asp.net/"&gt;ASP.NET AJAX&lt;/a&gt; 1.0. &lt;a href="http://www.nikhilk.net/Entry.aspx?id=152"&gt;Download
here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Quote from his blog (so you know why you should go and download them):
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;UpdateHistory&lt;/strong&gt;This is a non-visual control that allows you to
add history entries to the browser's navigation stack selectively for some post-backs,
and not for some others. This helps fix the back button to make it work, and allows
you to implement Ajax patterns such as "logical navigation" and unique URLs.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;StyledUpdatePanel&lt;/strong&gt;&amp;nbsp;A simple derived UpdatePanel that adds
CSS class semantics. A simple addition, but a useful feature, nevertheless, that didn't
make the feature cut.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;strong&gt;AnimatedUpdatePanel&lt;/strong&gt;&amp;nbsp;Another derived UpdatePanel that displays
new content using a variety of animations or effects: slides, wipes, cross-fades as
well as a visual highlight. This allows you to implement the "visual notification"
Ajax patterns such as the one second spotlight and one second mutation.&lt;/em&gt; 
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=b14cf193-1f1f-44e1-b973-f1a7fbde8ddc" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,b14cf193-1f1f-44e1-b973-f1a7fbde8ddc.aspx</comments>
      <category>ASP.NET</category>
      <category>Cool Download</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=fb56c8e8-c15f-4148-99a2-66abd43286da</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,fb56c8e8-c15f-4148-99a2-66abd43286da.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,fb56c8e8-c15f-4148-99a2-66abd43286da.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=fb56c8e8-c15f-4148-99a2-66abd43286da</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have been re-awarded <a href="http://mvp.support.microsoft.com/">MVP</a> for Visual
Developer ASP/ASP.NET. 
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=fb56c8e8-c15f-4148-99a2-66abd43286da" />
      </body>
      <title>MVP Visual Developer - ASP/ASP.NET Again 2007</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,fb56c8e8-c15f-4148-99a2-66abd43286da.aspx</guid>
      <link>http://chrison.net/MVPVisualDeveloperASPASPNETAgain2007.aspx</link>
      <pubDate>Wed, 03 Jan 2007 09:37:47 GMT</pubDate>
      <description>&lt;p&gt;
I have been re-awarded &lt;a href="http://mvp.support.microsoft.com/"&gt;MVP&lt;/a&gt; for Visual
Developer ASP/ASP.NET. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=fb56c8e8-c15f-4148-99a2-66abd43286da" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,fb56c8e8-c15f-4148-99a2-66abd43286da.aspx</comments>
      <category>ASP.NET</category>
      <category>Community</category>
      <category>this</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=29315c32-6296-4467-966d-2c32a76bd9cb</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,29315c32-6296-4467-966d-2c32a76bd9cb.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,29315c32-6296-4467-966d-2c32a76bd9cb.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=29315c32-6296-4467-966d-2c32a76bd9cb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I admit it: I am a regular reader of the event log. In doing so, I came across an
error message last week that I rarely get to see - invalid Viewstate:
</p>
        <p>
          <img src="http://chrison.net/content/binary/spaminviewstate.png" border="0" />
        </p>
        <p>
Now, that wouldn't be a problem, usually at least. However, in this special case I
went WTF? when I looked at the description more closely, especially at the PersistedState
information:
</p>
        <pre>PersistedState: a<br />
Content-Transfer-Encoding: 8bit<br />
Content-Type: text/plain<br />
X-Mailer: EMUmail 4.5<br />
Subject: jam n<br />
bcc: &lt;list of addresse removed by me /&gt;</pre>
        <pre>comes from the loin in the middle of the back of the pig. t is a lean meaty 
<br />
cut of bacon, with relatively less fat compared to other cuts. iddle bacon 
<br />
is much like back bacon</pre>
        <pre> </pre>
        <pre> </pre>
        <pre> </pre>
        <pre>daa6c5071189f202ceb370d0e9d38c33<br />
.</pre>
        <p>
Come again - spam in Viewstate? What would be the point of this? After some research
together with <a href="http://alexonasp.net/">Alex</a> I came across this article: <a href="http://www.anders.com/cms/75/Crack.Attempt/Spam.Relay">Interesting
Crack Attempt to Relay Spam</a> (a more detailed article is available too: <a href="http://www.anders.com/projects/sysadmin/formPostHijacking/">Form
Post Hijacking</a>). How did I manage to not take notice of this attack vector any
earlier I don't know, but I have to admit that the idea is pretty clever. 
</p>
        <p>
Counter-measures in general? Well, either don't allow users input in the headers at
all, or vet the form fields for carriage return / line feeds. Note that I did not
verify if any of the available mail components for .NET would be actually susceptible
to this kind of attack.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=29315c32-6296-4467-966d-2c32a76bd9cb" />
      </body>
      <title>Spam in ASP.NET Viewstate?</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,29315c32-6296-4467-966d-2c32a76bd9cb.aspx</guid>
      <link>http://chrison.net/SpamInASPNETViewstate.aspx</link>
      <pubDate>Wed, 22 Nov 2006 08:47:35 GMT</pubDate>
      <description>&lt;p&gt;
I admit it: I am a regular reader of the event log. In doing so, I came across an
error message last week that I rarely get to see - invalid Viewstate:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/spaminviewstate.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Now, that wouldn't be a problem, usually at least. However, in this special case I
went WTF? when I looked at the description more closely, especially at the PersistedState
information:
&lt;/p&gt;
&lt;pre&gt;PersistedState: a&lt;br&gt;
Content-Transfer-Encoding: 8bit&lt;br&gt;
Content-Type: text/plain&lt;br&gt;
X-Mailer: EMUmail 4.5&lt;br&gt;
Subject: jam n&lt;br&gt;
bcc: &amp;lt;list&gt;&amp;nbsp;of addresse removed by me /&amp;gt;&lt;/pre&gt;&lt;pre&gt;comes from the loin in the middle of the back of the pig. t is a lean meaty 
&lt;br&gt;
cut of bacon, with relatively less fat compared to other cuts. iddle bacon 
&lt;br&gt;
is much like back bacon&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;daa6c5071189f202ceb370d0e9d38c33&lt;br&gt;
.&lt;/pre&gt;
&lt;p&gt;
Come again - spam in Viewstate? What would be the point of this? After some research
together with &lt;a href="http://alexonasp.net/"&gt;Alex&lt;/a&gt; I came across this article: &lt;a href="http://www.anders.com/cms/75/Crack.Attempt/Spam.Relay"&gt;Interesting
Crack Attempt to Relay Spam&lt;/a&gt;&amp;nbsp;(a more detailed article is available too: &lt;a href="http://www.anders.com/projects/sysadmin/formPostHijacking/"&gt;Form
Post Hijacking&lt;/a&gt;). How did I manage to not take notice of this attack vector any
earlier I don't know, but I have to admit that the idea is pretty clever. 
&lt;/p&gt;
&lt;p&gt;
Counter-measures in general? Well, either don't allow users input in the headers at
all, or vet the form fields for carriage return / line feeds. Note that I did not
verify if any of the available mail components for .NET would be actually susceptible
to this kind of attack.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=29315c32-6296-4467-966d-2c32a76bd9cb" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,29315c32-6296-4467-966d-2c32a76bd9cb.aspx</comments>
      <category>ASP.NET</category>
      <category>Security</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=12cc87b1-a461-442f-8a49-7eff8aea58dd</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,12cc87b1-a461-442f-8a49-7eff8aea58dd.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,12cc87b1-a461-442f-8a49-7eff8aea58dd.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=12cc87b1-a461-442f-8a49-7eff8aea58dd</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
From the <a href="http://www.microsoft.com/uk/msdn/events/nuggets.aspx">nuggets page</a>: <em>Don't
have the time to read a 10-page how-to article or watch a full length webcast? Try
an MSDN Nugget, a webcast that takes you step-by-step to discovering new functionality
or exploring a hot developer topic, all in 10-15 minutes.</em> If you haven't seen
this yet, check it out!
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=12cc87b1-a461-442f-8a49-7eff8aea58dd" />
      </body>
      <title>MSDN Nuggets</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,12cc87b1-a461-442f-8a49-7eff8aea58dd.aspx</guid>
      <link>http://chrison.net/MSDNNuggets.aspx</link>
      <pubDate>Wed, 08 Nov 2006 14:04:26 GMT</pubDate>
      <description>&lt;p&gt;
From the &lt;a href="http://www.microsoft.com/uk/msdn/events/nuggets.aspx"&gt;nuggets page&lt;/a&gt;: &lt;em&gt;Don't
have the time to read a 10-page how-to article or watch a full length webcast? Try
an MSDN Nugget, a webcast that takes you step-by-step to discovering new functionality
or exploring a hot developer topic, all in 10-15 minutes.&lt;/em&gt; If you haven't seen
this yet, check it out!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=12cc87b1-a461-442f-8a49-7eff8aea58dd" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,12cc87b1-a461-442f-8a49-7eff8aea58dd.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>BCL</category>
      <category>Training and Conferences</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=d4dcfd3f-4980-4f1c-b2a0-2c3692915418</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,d4dcfd3f-4980-4f1c-b2a0-2c3692915418.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,d4dcfd3f-4980-4f1c-b2a0-2c3692915418.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=d4dcfd3f-4980-4f1c-b2a0-2c3692915418</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today, <a href="http://geekswithblogs.net/danielz/">Daniel</a> held a talk comparing
AJAX frameworks for ASP.NET. He limited the scope to indirect frameworks, which means:
those AJAX frameworks extend ASP.NET, and you don't necessarily need to know much
about AJAX. On his Web site, you will find a <a href="http://www.daniel-zeiss.de/AJAXComparison/Results.htm">comparison
of AJAX frameworks for ASP.NET</a> (direct as well as indirect).
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=d4dcfd3f-4980-4f1c-b2a0-2c3692915418" />
      </body>
      <title>AJAX Frameworks for ASP.NET Comparison</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,d4dcfd3f-4980-4f1c-b2a0-2c3692915418.aspx</guid>
      <link>http://chrison.net/AJAXFrameworksForASPNETComparison.aspx</link>
      <pubDate>Wed, 21 Jun 2006 12:42:50 GMT</pubDate>
      <description>&lt;p&gt;
Today, &lt;a href="http://geekswithblogs.net/danielz/"&gt;Daniel&lt;/a&gt; held a talk comparing
AJAX frameworks for ASP.NET. He limited the scope to indirect frameworks, which means:
those AJAX frameworks extend ASP.NET, and you don't necessarily need to know much
about AJAX. On his Web site, you will find a &lt;a href="http://www.daniel-zeiss.de/AJAXComparison/Results.htm"&gt;comparison
of AJAX frameworks for ASP.NET&lt;/a&gt; (direct as well as indirect).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=d4dcfd3f-4980-4f1c-b2a0-2c3692915418" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,d4dcfd3f-4980-4f1c-b2a0-2c3692915418.aspx</comments>
      <category>ASP.NET</category>
      <category>Training and Conferences</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=63ed6209-de4f-4803-8f7f-114810579808</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,63ed6209-de4f-4803-8f7f-114810579808.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,63ed6209-de4f-4803-8f7f-114810579808.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=63ed6209-de4f-4803-8f7f-114810579808</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
As promised, here is the list of links / articles / samples that I used for preparing
my talk "Build Provider in ASP.NET 2.0":
</p>
        <ul>
          <li>
            <a href="http://msdn.microsoft.com/asp.net/downloads/providers/">Provider Toolkit</a>
          </li>
          <li>
            <a href="http://www.codeproject.com/aspnet/custombuildproviders.asp">Extending ASP.NET
2.0 Part I: Creating Custom Build Providers</a>
          </li>
          <li>
            <a href="http://pluralsight.com/blogs/fritz/archive/2004/09/06/2188.aspx">Jaw-dropping
experience with custom build providers</a>
          </li>
          <li>
            <a href="http://weblogs.asp.net/aaguiar/archive/2005/12/14/433143.aspx">DLINQ ASP.NET
Build Provider and DLINQ DataSource</a> (Andres sent me a newer version for the
May CTP)</li>
          <li>
            <a href="http://blogs.msdn.com/dmitryr/archive/2006/03/26/561200.aspx">RSS Toolkit</a> (sports
two build providers, one for .rssdl, the other for .rss)</li>
          <li>
            <a href="http://blogs.msdn.com/kaevans/archive/2005/09/02/460231.aspx">Web Services
Contract First: Drop Schema in app_code with a Custom Build Provider</a>
          </li>
        </ul>
        <p>
Hope you will find those useful.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=63ed6209-de4f-4803-8f7f-114810579808" />
      </body>
      <title>Talk Resources: ASP.NET Build Provider</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,63ed6209-de4f-4803-8f7f-114810579808.aspx</guid>
      <link>http://chrison.net/TalkResourcesASPNETBuildProvider.aspx</link>
      <pubDate>Tue, 20 Jun 2006 11:14:32 GMT</pubDate>
      <description>&lt;p&gt;
As promised, here is the list of links / articles / samples that I used for preparing
my talk "Build Provider in ASP.NET 2.0":
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://msdn.microsoft.com/asp.net/downloads/providers/"&gt;Provider Toolkit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.codeproject.com/aspnet/custombuildproviders.asp"&gt;Extending ASP.NET
2.0 Part I: Creating Custom Build Providers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://pluralsight.com/blogs/fritz/archive/2004/09/06/2188.aspx"&gt;Jaw-dropping
experience with custom build providers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://weblogs.asp.net/aaguiar/archive/2005/12/14/433143.aspx"&gt;DLINQ ASP.NET
Build Provider and DLINQ DataSource&lt;/a&gt;&amp;nbsp;(Andres sent me a newer version for the
May CTP)&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://blogs.msdn.com/dmitryr/archive/2006/03/26/561200.aspx"&gt;RSS Toolkit&lt;/a&gt;&amp;nbsp;(sports
two build providers, one for .rssdl, the other for .rss)&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://blogs.msdn.com/kaevans/archive/2005/09/02/460231.aspx"&gt;Web Services
Contract First: Drop Schema in app_code with a Custom Build Provider&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Hope you will find those useful.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=63ed6209-de4f-4803-8f7f-114810579808" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,63ed6209-de4f-4803-8f7f-114810579808.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>this</category>
      <category>Training and Conferences</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=6ee03559-ed16-421a-9df5-42f36b9d77a2</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,6ee03559-ed16-421a-9df5-42f36b9d77a2.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,6ee03559-ed16-421a-9df5-42f36b9d77a2.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=6ee03559-ed16-421a-9df5-42f36b9d77a2</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Half an hour ago, I completed my talk "Windows Workflow Foundation &amp; ASP.NET 2.0".
As promised, here is the list of links to sites / documents that I used to prepare
this talk &amp; accompanying samples.
</p>
        <ul>
          <li>
            <a href="http://blogs.msdn.com/pandrew/archive/2006/04/28/586181.aspx">Coming improvements
to ASP.NET hosting of Windows Workflow Foundation after WF Beta 2.2</a>
          </li>
          <li>
Cutting Edge, Windows Workflow Foundation <a href="http://msdn.microsoft.com/msdnmag/issues/06/03/CuttingEdge/">Part
1</a>, <a href="http://msdn.microsoft.com/msdnmag/issues/06/04/CuttingEdge/">Part
2</a></li>
          <li>
            <a href="http://blogs.msdn.com/tomlake/archive/2006/05/17/600143.aspx">Examples of
using Persistence and Tracking in ASP.NET</a>
          </li>
          <li>
            <a href="http://www.masteringbiztalk.com/blogs/jon/PermaLink,guid,0fae3e73-7801-4cf6-a5a5-9370b0f99973.aspx">Using
WF to run a page-flow</a>
          </li>
          <li>
Of course, <a href="http://wf.netfx3.com/">http://wf.netfx3.com/</a> (Webcasts
et al)</li>
        </ul>
        <p>
Also, see <a href="http://chrison.net/ASPNETWindowsWorkflowFoundationVNext.aspx">my
last post on ASP.NET PageFlow CTP</a>. This was the last part on "future technologies".
</p>
        <p>
          <strong>Update</strong> A foto from my talk on Monday (debugging a workflow in ASP.NET):
</p>
        <p>
          <img src="http://chrison.net/content/binary/wftalkfoto_courtesyaspkonferenz2006.jpg" border="0" />
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=6ee03559-ed16-421a-9df5-42f36b9d77a2" />
      </body>
      <title>Talk Resources: WF &amp; ASP.NET</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,6ee03559-ed16-421a-9df5-42f36b9d77a2.aspx</guid>
      <link>http://chrison.net/TalkResourcesWFASPNET.aspx</link>
      <pubDate>Mon, 19 Jun 2006 09:39:07 GMT</pubDate>
      <description>&lt;p&gt;
Half an hour ago, I completed my talk "Windows Workflow Foundation &amp;amp; ASP.NET 2.0".
As promised, here is the list of links to sites / documents that I used to prepare
this talk &amp;amp; accompanying samples.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://blogs.msdn.com/pandrew/archive/2006/04/28/586181.aspx"&gt;Coming improvements
to ASP.NET hosting of Windows Workflow Foundation after WF Beta 2.2&lt;/a&gt; 
&lt;li&gt;
Cutting Edge,&amp;nbsp;Windows Workflow Foundation &lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/03/CuttingEdge/"&gt;Part
1&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/04/CuttingEdge/"&gt;Part
2&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://blogs.msdn.com/tomlake/archive/2006/05/17/600143.aspx"&gt;Examples of
using Persistence and Tracking in ASP.NET&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://www.masteringbiztalk.com/blogs/jon/PermaLink,guid,0fae3e73-7801-4cf6-a5a5-9370b0f99973.aspx"&gt;Using
WF to run a page-flow&lt;/a&gt; 
&lt;li&gt;
Of course, &lt;a href="http://wf.netfx3.com/"&gt;http://wf.netfx3.com/&lt;/a&gt;&amp;nbsp;(Webcasts
et al)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Also, see &lt;a href="http://chrison.net/ASPNETWindowsWorkflowFoundationVNext.aspx"&gt;my
last post on ASP.NET PageFlow CTP&lt;/a&gt;. This was the last part on "future technologies".
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update&lt;/strong&gt; A foto from my talk on Monday (debugging a workflow in ASP.NET):
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/wftalkfoto_courtesyaspkonferenz2006.jpg" border=0&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=6ee03559-ed16-421a-9df5-42f36b9d77a2" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,6ee03559-ed16-421a-9df5-42f36b9d77a2.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>this</category>
      <category>Training and Conferences</category>
      <category>Tri 0</category>
      <category>Workflow Foundation</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=478b2644-93cc-43ab-86e3-30f29b9c45c5</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,478b2644-93cc-43ab-86e3-30f29b9c45c5.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,478b2644-93cc-43ab-86e3-30f29b9c45c5.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=478b2644-93cc-43ab-86e3-30f29b9c45c5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Yesterday night, I watched a WebCast from TechEd Boston - "An Overview of ASP.NET
and Windows Workflow Foundation". What this innocuous title hid was the fact that
Kashif Alam (PM in the Developer Division) was presenting vNext features for ASP.NET
workflow integration: Page flow (PageFlow) as well as UI flow (UIFlow), plus the accompanying
extensibility model.
</p>
        <p>
What do those two separate approaches provide? Well, you get MVC (model-view-controller) support
for same-page (UIFlow) as well as cross-page (PageFlow) scenarios. Pretty
neat was the included "Choosing the right solution" slide to get an idea what's in
store:
</p>
        <table border="1">
          <tbody>
            <tr>
              <th>
Task</th>
              <th>
&lt;asp:wizard...&gt;</th>
              <th>
PageFlow</th>
              <th>
UIFlow</th>
            </tr>
            <tr>
              <td>
Single page</td>
              <td>
x</td>
              <td>
              </td>
              <td>
x</td>
            </tr>
            <tr>
              <td>
Multiple pages</td>
              <td>
              </td>
              <td>
x</td>
              <td>
              </td>
            </tr>
            <tr>
              <td>
State when close browser</td>
              <td>
              </td>
              <td>
x</td>
              <td>
x</td>
            </tr>
            <tr>
              <td>
Integrate with Enterprise WF</td>
              <td>
              </td>
              <td>
x</td>
              <td>
x</td>
            </tr>
            <tr>
              <td>
Client support</td>
              <td>
              </td>
              <td>
x</td>
              <td>
x</td>
            </tr>
            <tr>
              <td>
Built-in navigation UI</td>
              <td>
x</td>
              <td>
              </td>
              <td>
              </td>
            </tr>
            <tr>
              <td>
Extensibility to other controllers</td>
              <td>
              </td>
              <td>
x</td>
              <td>
x</td>
            </tr>
          </tbody>
        </table>
        <p>
As developers, we will get our hands on this later this year in the form of the "ASP.NET
PageFlow CTP" (at least that's the current name), and it will be deployed with Orcas.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=478b2644-93cc-43ab-86e3-30f29b9c45c5" />
      </body>
      <title>ASP.NET &amp; Windows Workflow Foundation vNext</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,478b2644-93cc-43ab-86e3-30f29b9c45c5.aspx</guid>
      <link>http://chrison.net/ASPNETWindowsWorkflowFoundationVNext.aspx</link>
      <pubDate>Tue, 13 Jun 2006 06:28:38 GMT</pubDate>
      <description>&lt;p&gt;
Yesterday night, I watched a WebCast from TechEd Boston - "An Overview of ASP.NET
and Windows Workflow Foundation". What this innocuous title hid was the fact that
Kashif Alam (PM in the Developer Division) was presenting vNext features for ASP.NET
workflow integration: Page flow (PageFlow) as well as UI flow (UIFlow), plus the accompanying
extensibility model.
&lt;/p&gt;
&lt;p&gt;
What do those two separate approaches provide? Well, you get MVC (model-view-controller)&amp;nbsp;support
for same-page (UIFlow)&amp;nbsp;as well as cross-page (PageFlow)&amp;nbsp;scenarios. Pretty
neat was the included "Choosing the right solution" slide to get an idea what's in
store:
&lt;/p&gt;
&lt;table border=1&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;
Task&lt;/th&gt;
&lt;th&gt;
&amp;lt;asp:wizard...&amp;gt;&lt;/th&gt;
&lt;th&gt;
PageFlow&lt;/th&gt;
&lt;th&gt;
UIFlow&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Single page&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Multiple pages&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
State when close browser&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Integrate with Enterprise WF&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Client support&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Built-in navigation UI&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
Extensibility to other controllers&lt;/td&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;td&gt;
x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
As developers, we will get our hands on this later this year in the form of the "ASP.NET
PageFlow CTP" (at least that's the current name), and it will be deployed with Orcas.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=478b2644-93cc-43ab-86e3-30f29b9c45c5" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,478b2644-93cc-43ab-86e3-30f29b9c45c5.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Tri 0</category>
      <category>Workflow Foundation</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=ca32f8e8-da7a-4bed-8331-ebad728d2fd5</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,ca32f8e8-da7a-4bed-8331-ebad728d2fd5.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,ca32f8e8-da7a-4bed-8331-ebad728d2fd5.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ca32f8e8-da7a-4bed-8331-ebad728d2fd5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It is has landed, you can download the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=B01DC501-B3C1-4EC0-93F0-7DAC68D2F787&amp;displaylang=en">Atlas
March CTP here</a>. More information on Atlas itself can be found on the <a href="http://atlas.asp.net/">official
Atlas site</a>.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=ca32f8e8-da7a-4bed-8331-ebad728d2fd5" />
      </body>
      <title>ASP.NET Atlas March CTP</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,ca32f8e8-da7a-4bed-8331-ebad728d2fd5.aspx</guid>
      <link>http://chrison.net/ASPNETAtlasMarchCTP.aspx</link>
      <pubDate>Mon, 20 Mar 2006 17:18:11 GMT</pubDate>
      <description>&lt;p&gt;
It is has landed, you can download the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=B01DC501-B3C1-4EC0-93F0-7DAC68D2F787&amp;amp;displaylang=en"&gt;Atlas
March CTP here&lt;/a&gt;. More information on Atlas itself can be found on the &lt;a href="http://atlas.asp.net/"&gt;official
Atlas site&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=ca32f8e8-da7a-4bed-8331-ebad728d2fd5" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,ca32f8e8-da7a-4bed-8331-ebad728d2fd5.aspx</comments>
      <category>ASP.NET</category>
      <category>Cool Download</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=edf362a3-ff2c-4d36-9b06-29c4bab6b4d1</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,edf362a3-ff2c-4d36-9b06-29c4bab6b4d1.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,edf362a3-ff2c-4d36-9b06-29c4bab6b4d1.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=edf362a3-ff2c-4d36-9b06-29c4bab6b4d1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
On my flight to Seattle today (or yesterday, depending on the time zone) I started
to read <a href="http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764596985.html">Professional
ASP.NET 2.0 Security, Membership, and Role Management</a> by Stefan Schackow. The
book definitely is a must-have for every ASP.NET developer, even if you decide to
read one chapter only: A Matter of Trust (#3). This one will save you loads of time
when you have to deploy an application into non-full trust environments. However,
the other chapters are worthwhile too, like #2 which details exactly which identity
is used when by what part of the engine. Bottomline: highly recommended reading.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=edf362a3-ff2c-4d36-9b06-29c4bab6b4d1" />
      </body>
      <title>Professional ASP.NET 2.0 Security, Membership, and Role Management</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,edf362a3-ff2c-4d36-9b06-29c4bab6b4d1.aspx</guid>
      <link>http://chrison.net/ProfessionalASPNET20SecurityMembershipAndRoleManagement.aspx</link>
      <pubDate>Sun, 19 Feb 2006 08:21:00 GMT</pubDate>
      <description>&lt;p&gt;
On my flight to Seattle today (or yesterday, depending on the time zone) I started
to read &lt;a href="http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764596985.html"&gt;Professional
ASP.NET 2.0 Security, Membership, and Role Management&lt;/a&gt; by Stefan Schackow. The
book definitely is a must-have for every ASP.NET developer, even if you decide to
read one chapter only: A Matter of Trust (#3). This one will save you loads of time
when you have to deploy an application into non-full trust environments. However,
the other chapters are worthwhile too, like #2 which details exactly which identity
is used when by what part of the engine. Bottomline: highly recommended reading.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=edf362a3-ff2c-4d36-9b06-29c4bab6b4d1" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,edf362a3-ff2c-4d36-9b06-29c4bab6b4d1.aspx</comments>
      <category>.NET</category>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Books</category>
      <category>Security</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=b6f33c00-3cc2-41e3-a761-45ce46a93d3a</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,b6f33c00-3cc2-41e3-a761-45ce46a93d3a.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,b6f33c00-3cc2-41e3-a761-45ce46a93d3a.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=b6f33c00-3cc2-41e3-a761-45ce46a93d3a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Yesterday, I picked up on an old code piece of mine - sending images to the client
via an HttpHandler. Why in the world would you implement that with a handler when
there is http.sys kernel mode caching? Well, I had a few unique constraints:
</p>
        <ul>
          <li>
the images had to live outside the Web root and any of its vroots 
</li>
          <li>
the image names had to be concealed because the naming would give away information,
and renaming the images prior to publishing on the Web was out of the question</li>
        </ul>
        <p>
Now, a common approach to sending images from a certain directory (leaving requirement
#2 by the wayside for the moment) would be this:
</p>
        <pre>image.aspx?image=iamthebest.jpg</pre>
        <p>
So what is wrong with this approach? First and foremost using an ASP.NET page. The
page lifecycle is a drain on performance and throughput, because you simply don't
need it. That sorts out why I chose to go with an HTTP handler.
</p>
        <p>
Secondly, somebody could DOS your server. You heard me right. For the background,
check the article <a href="http://www.aspheute.com/english/20020131.asp">Trap Alert:
Files that aren't</a>. A .NET version (managed C++) of this checker can be found
in <a href="http://www.aspheute.com/Code/20020201.zip">this download</a> (the
article <a href="http://www.aspheute.com/artikel/20020201.htm">Dateityp-Ermittlung
in Managed C++</a> is only available in German). 
</p>
        <p>
How do you get around this issue? Well, how about reading the directory up front,
and instead of having the filename in the URL, send the hash! When the image is requested,
take the hash and look up the corresponding file, presto. In addition you get one
security feature for free: no directory traversals can be hidden in your code.
</p>
        <p>
When I uncovered the code yesterday, I decided to rewrite it for more general use.
So what do you get? 
</p>
        <ul>
          <li>
The ImageCacheControls project: it contains the ImageCache class, which does most
of the heavy lifting. In addition, you get an ImageCacheControl server control, as
well as the implementation of the HTTP handler. (Don't forget to check out the Readme.txt
for the latest on feature set and known issues) 
</li>
          <li>
The Web project: a rather simple Web site with demo files in it. The file I want to
direct your attention to is Image.ashx. This is the one file - aside from the control
project binaries - that needs to be copied to your projects to get started with ImageCache.
Note that I made it easy to work with C# (default) or VB.NET.</li>
        </ul>
        <p>
Usage of ImageCache is demonstrated in default.aspx.cs plus the source code of default.aspx
(design time of the control does not work, known issue). 
</p>
        <p>
The code behind looks like this (<em>CreateMapping</em> loads the directory contents,
initializes the hash to file name map, stores it into the cache):
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> ChrisOnNET.ImageCache;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> partial <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> _Default
: System.Web.UI.Page 
<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
protected</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Page_Load(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
EventArgs e)<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span>{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span>//
normally, this would be done in global.asax</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span>ImageCache.CreateMapping(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"demo"</span>,
Server.MapPath(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"~/TestImages/"</span>));<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span>//
the DIY approach to rendering the image tag</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span>string</span> testHash <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ImageCache.GetHashForFile(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"026.jpg"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"demo"</span>);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span>Response.Write(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"&lt;image
src=\"Image.ashx?bucket="</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><br /><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span></span>"demo"</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><br /><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span></span>"&amp;image="</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span></span>Server.UrlEncode(testHash) <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><br /><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span></span>"\"
/&gt;"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span>//
the elegant approach to rendering the image tag</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span>Response.Write(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"&lt;image
src=\""</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> ImageCache.GenerateUrl(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"036.jpg"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"demo"</span>) <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><br /><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span>"\"
/&gt;"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span></span>//
see HTML source for server control approach (Design time not working, known issue)</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   </span>}<br />
}</span>
        </p>
        <p>
Rendering Image tags in Page_Load isn't nice, but after all it is only intended to
show the functionality. Most likely you are going to use the declarative <em>ImageCacheControl</em> anyways:
</p>
        <pre>&lt;%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %&gt;<br />
&lt;%@ Register Assembly="ImageCacheControls" Namespace="ChrisOnNET.ImageCache" TagPrefix="cc1"
%&gt;</pre>
        <pre>&lt;html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"
&gt;<br />
&lt;head runat="server"&gt;<br />
    &lt;title&gt;Untitled Page&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
    &lt;form id="form1" runat="server"&gt;<br />
    &lt;div&gt;<br />
        &lt;br /&gt;Using the ImageCacheControl:&amp;nbsp;<br />
        &lt;cc1:ImageCacheControl ID="ImageCacheControl1" 
<br />
            Bucket="demo"<br />
            FileName="026.jpg"<br />
            runat="server"
/&gt;<br />
    &lt;/div&gt;<br />
    &lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</pre>
        <p>
That's basically it. Let me know what you think.
</p>
        <p>
          <a href="http://chrison.net/content/binary/ImageCacheTakeOne.zip">ImageCacheTakeOne.zip
(59.55 KB)</a>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=b6f33c00-3cc2-41e3-a761-45ce46a93d3a" />
      </body>
      <title>ImageCache, Take One</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,b6f33c00-3cc2-41e3-a761-45ce46a93d3a.aspx</guid>
      <link>http://chrison.net/ImageCacheTakeOne.aspx</link>
      <pubDate>Wed, 18 Jan 2006 10:21:05 GMT</pubDate>
      <description>&lt;p&gt;
Yesterday, I picked up on an old code piece of mine - sending images to the client
via an HttpHandler. Why in the world would you implement that with a handler when
there is http.sys kernel mode caching? Well, I had a few unique constraints:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
the images had to live outside the Web root and any of its vroots 
&lt;li&gt;
the image names had to be concealed because the naming would give away information,
and renaming the images prior to publishing on the Web was out of the question&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Now, a common approach to sending images from a certain directory (leaving requirement
#2 by the wayside for the moment) would be this:
&lt;/p&gt;
&lt;pre&gt;image.aspx?image=iamthebest.jpg&lt;/pre&gt;
&lt;p&gt;
So what is wrong with this approach? First and foremost using an ASP.NET page. The
page lifecycle is a drain on performance and throughput, because you simply don't
need it. That sorts out why I chose to go with an HTTP handler.
&lt;/p&gt;
&lt;p&gt;
Secondly, somebody could DOS your server. You heard me right. For the background,
check the article &lt;a href="http://www.aspheute.com/english/20020131.asp"&gt;Trap Alert:
Files that aren't&lt;/a&gt;. A .NET version (managed C++)&amp;nbsp;of this checker can be found
in &lt;a href="http://www.aspheute.com/Code/20020201.zip"&gt;this download&lt;/a&gt;&amp;nbsp;(the
article &lt;a href="http://www.aspheute.com/artikel/20020201.htm"&gt;Dateityp-Ermittlung
in Managed C++&lt;/a&gt; is only available in German). 
&lt;/p&gt;
&lt;p&gt;
How do you get around this issue? Well, how about reading the directory up front,
and instead of having the filename in the URL, send the hash! When the image is requested,
take the hash and look up the corresponding file, presto. In addition you get one
security feature for free: no directory traversals can be hidden in your code.
&lt;/p&gt;
&lt;p&gt;
When I uncovered the code yesterday, I decided to rewrite it for more general use.
So what do you get? 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The ImageCacheControls project: it contains the ImageCache class, which does most
of the heavy lifting. In addition, you get an ImageCacheControl server control, as
well as the implementation of the HTTP handler. (Don't forget to check out the Readme.txt
for the latest on feature set and known issues) 
&lt;li&gt;
The Web project: a rather simple Web site with demo files in it. The file I want to
direct your attention to is Image.ashx. This is the one file - aside from the control
project binaries - that needs to be copied to your projects to get started with ImageCache.
Note that I made it easy to work with C# (default) or VB.NET.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Usage of ImageCache is demonstrated in default.aspx.cs plus the source code of default.aspx
(design time of the control does not work, known issue). 
&lt;/p&gt;
&lt;p&gt;
The code behind looks like this (&lt;em&gt;CreateMapping&lt;/em&gt; loads the directory contents,
initializes the hash to file name map, stores it into the cache):
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; ChrisOnNET.ImageCache;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; partial &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; _Default
: System.Web.UI.Page 
&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Page_Load(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
EventArgs e)&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;//
normally, this would be done in global.asax&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;ImageCache.CreateMapping(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"demo"&lt;/span&gt;,
Server.MapPath(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"~/TestImages/"&lt;/span&gt;));&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;//
the DIY approach to rendering the image tag&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;string&lt;/span&gt; testHash &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ImageCache.GetHashForFile(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"026.jpg"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"demo"&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Response.Write(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"&amp;lt;image
src=\"Image.ashx?bucket="&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;"demo"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;"&amp;amp;image="&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Server.UrlEncode(testHash) &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;"\"
/&amp;gt;"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;//
the elegant approach to rendering the image tag&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Response.Write(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"&amp;lt;image
src=\""&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; ImageCache.GenerateUrl(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"036.jpg"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"demo"&lt;/span&gt;) &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;"\"
/&amp;gt;"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;//
see HTML source for server control approach (Design time not working, known issue)&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Rendering Image tags in Page_Load isn't nice, but after all it is only intended to
show the functionality. Most likely you are going to use the declarative &lt;em&gt;ImageCacheControl&lt;/em&gt; anyways:
&lt;/p&gt;
&lt;pre&gt;&amp;lt;%@ Page Language="C#" AutoEventWireup="true"&amp;nbsp; CodeFile="Default.aspx.cs" Inherits="_Default" %&amp;gt;&lt;br&gt;
&amp;lt;%@ Register Assembly="ImageCacheControls" Namespace="ChrisOnNET.ImageCache" TagPrefix="cc1"
%&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;html xmlns="&lt;a href="http://www.w3.org/1999/xhtml"&gt;http://www.w3.org/1999/xhtml&lt;/a&gt;"
&amp;gt;&lt;br&gt;
&amp;lt;head runat="server"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;Untitled Page&amp;lt;/title&amp;gt;&lt;br&gt;
&amp;lt;/head&amp;gt;&lt;br&gt;
&amp;lt;body&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;form id="form1" runat="server"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;br /&amp;gt;Using the ImageCacheControl:&amp;amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;cc1:ImageCacheControl ID="ImageCacheControl1" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Bucket="demo"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileName="026.jpg"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; runat="server"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/form&amp;gt;&lt;br&gt;
&amp;lt;/body&amp;gt;&lt;br&gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;
&lt;p&gt;
That's basically it. Let me know what you think.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/ImageCacheTakeOne.zip"&gt;ImageCacheTakeOne.zip
(59.55 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=b6f33c00-3cc2-41e3-a761-45ce46a93d3a" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,b6f33c00-3cc2-41e3-a761-45ce46a93d3a.aspx</comments>
      <category>.NET</category>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Use the source Luke</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=8da2b45e-3dca-478d-a552-e07ee3c78af5</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,8da2b45e-3dca-478d-a552-e07ee3c78af5.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,8da2b45e-3dca-478d-a552-e07ee3c78af5.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=8da2b45e-3dca-478d-a552-e07ee3c78af5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today, I got my <a href="http://mvp.support.microsoft.com/">MVP</a> award package,
which kind of makes it fully official. No surprise with my area of expertise:
Visual Developer ASP / ASP.NET.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=8da2b45e-3dca-478d-a552-e07ee3c78af5" />
      </body>
      <title>MVP 2006</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,8da2b45e-3dca-478d-a552-e07ee3c78af5.aspx</guid>
      <link>http://chrison.net/MVP2006.aspx</link>
      <pubDate>Mon, 09 Jan 2006 17:20:44 GMT</pubDate>
      <description>&lt;p&gt;
Today, I got my &lt;a href="http://mvp.support.microsoft.com/"&gt;MVP&lt;/a&gt; award package,
which kind of makes it fully official. No surprise with my&amp;nbsp;area of expertise:
Visual Developer ASP / ASP.NET.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=8da2b45e-3dca-478d-a552-e07ee3c78af5" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,8da2b45e-3dca-478d-a552-e07ee3c78af5.aspx</comments>
      <category>ASP.NET</category>
      <category>Community</category>
      <category>this</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=5ed6ea95-2567-4aa1-a3a8-8886802f8bfa</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,5ed6ea95-2567-4aa1-a3a8-8886802f8bfa.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,5ed6ea95-2567-4aa1-a3a8-8886802f8bfa.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=5ed6ea95-2567-4aa1-a3a8-8886802f8bfa</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you have ASP.NET 1.1 and ASP.NET 2.0 on an x64 machine, you better read the
KB article <a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;894435">How
to switch between the 32-bit versions of ASP.NET 1.1 and the 64-bit version of ASP.NET
2.0 on a 64-bit version of Windows</a>.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=5ed6ea95-2567-4aa1-a3a8-8886802f8bfa" />
      </body>
      <title>32 Bit and 64 Bit on IIS</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,5ed6ea95-2567-4aa1-a3a8-8886802f8bfa.aspx</guid>
      <link>http://chrison.net/32BitAnd64BitOnIIS.aspx</link>
      <pubDate>Thu, 29 Dec 2005 11:15:48 GMT</pubDate>
      <description>&lt;p&gt;
If you have ASP.NET 1.1 and ASP.NET 2.0 on an&amp;nbsp;x64 machine, you better read the
KB article &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;894435"&gt;How
to switch between the 32-bit versions of ASP.NET 1.1 and the 64-bit version of ASP.NET
2.0 on a 64-bit version of Windows&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=5ed6ea95-2567-4aa1-a3a8-8886802f8bfa" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,5ed6ea95-2567-4aa1-a3a8-8886802f8bfa.aspx</comments>
      <category>ASP.NET</category>
      <category>x64</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=ef3e6b4b-9ac4-455b-b784-837646d5e8b4</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,ef3e6b4b-9ac4-455b-b784-837646d5e8b4.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,ef3e6b4b-9ac4-455b-b784-837646d5e8b4.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ef3e6b4b-9ac4-455b-b784-837646d5e8b4</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today, a member of our <a href="http://www.dotnetgerman.com/">German .NET community</a> asked
if it is possible to programmatically query the Google page rank. He had seen it done
in PHP (<a href="http://www.googlecommunity.com/scripts/pagerank-source.phps">here</a> on
the <a href="http://www.googlecommunity.com/">Google Community</a> site), but didn't
have time / PHP skills to translate it. All I found on a rather shallow search was <a href="http://www.bolinfest.com/pullrank/">PullRank</a>,
which I'd describe as non-fit for server use.
</p>
        <p>
So I decided to set out to convert the PHP sample. Being PHP-challenged myself, I
decided to give the <a href="http://msdn.microsoft.com/asp.net/using/migrating/phpmig/phpmigasst.aspx">PHP
to ASP.NET Migration Assistant</a> a shot. Whoha! That converted code is the most
convoluted contraption to be called code I have seen - ever. I tried to get it to
run, but failed because the conversion left me with some loose ends.
</p>
        <p>
Instead of giving in, I contacted <a href="http://www.hauser-wenz.de/s9y/">Christian
Wenz</a> to lend me a hand because he has some PHP experience. He thankfully hosted
an "annotated" version of the PHP script so I could look at the output of
various stages to test my solution with known-good values. That was most helpful.
</p>
        <p>
Instead of doing a Web site demo application with everything intertwined, I split
up the project into two - <strong>GPRDotNet</strong> being a DLL assembly project
you can reference in any type of .NET application (Windows Forms, Web Forms, you name
it), as well as a simple Web frontend to demo the usage: <strong>DemoSite</strong>.
</p>
        <p>
          <img src="http://chrison.net/content/binary/GooglePageRankInDotNet20.png" border="0" />
        </p>
        <p>
Querying the page rank is really simple - the following snippet is the code
from the "Check PageRank" button event handler:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">protected</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> doCheckPageRank_Click(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
EventArgs e)<br />
{<br />
  GooglePageRank pr <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> GooglePageRank();<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">  </font>string</span> url <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> webSiteUrl.Text;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">  </font>try</span><br />
  {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">    </font>string</span> rank <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> pr.GetRank(url);<br />
    thePageRank.Text <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> rank;<br />
  }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">  </font>catch</span> (Exception
ex)<br />
  {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">    </font>//
this is rather chatty (telling the end user everything *IS* a bad idea)</span><br />
    thePageRank.Text <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Requesting
the page rank failed. Reason: "</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> ex.ToString();<br />
  }<br />
}</span>
        </p>
        <p>
I want to emphasize that the code for the GooglePageRank class is a rather quick &amp;
dirty port of the PHP code and that it does not contain the necessary error handling
you would expect for a server-side library. After all, it is just a proof of concept
for our community.
</p>
        <p>
Finally, here is the source code: <a href="http://chrison.net/content/binary/PageRank.zip">PageRank.zip
(26.89 KB)</a></p>
        <p>
If you find errors, please leave a blog comment so others know about improvements.
Thanks!
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=ef3e6b4b-9ac4-455b-b784-837646d5e8b4" />
      </body>
      <title>Google PageRank as a .NET Assembly</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,ef3e6b4b-9ac4-455b-b784-837646d5e8b4.aspx</guid>
      <link>http://chrison.net/GooglePageRankAsANETAssembly.aspx</link>
      <pubDate>Mon, 05 Dec 2005 18:03:00 GMT</pubDate>
      <description>&lt;p&gt;
Today, a member of our &lt;a href="http://www.dotnetgerman.com/"&gt;German .NET community&lt;/a&gt; asked
if it is possible to programmatically query the Google page rank. He had seen it done
in PHP (&lt;a href="http://www.googlecommunity.com/scripts/pagerank-source.phps"&gt;here&lt;/a&gt;&amp;nbsp;on
the &lt;a href="http://www.googlecommunity.com/"&gt;Google Community&lt;/a&gt; site), but didn't
have time / PHP skills to translate it. All I found on a rather shallow search was &lt;a href="http://www.bolinfest.com/pullrank/"&gt;PullRank&lt;/a&gt;,
which I'd describe as&amp;nbsp;non-fit for server use.
&lt;/p&gt;
&lt;p&gt;
So I decided to set out to convert the PHP sample. Being PHP-challenged myself, I
decided to give the &lt;a href="http://msdn.microsoft.com/asp.net/using/migrating/phpmig/phpmigasst.aspx"&gt;PHP
to ASP.NET Migration Assistant&lt;/a&gt; a shot. Whoha! That converted code is the most
convoluted contraption to be called code I have seen - ever. I tried to get it to
run, but failed because the conversion left me with some loose ends.
&lt;/p&gt;
&lt;p&gt;
Instead of giving in, I contacted &lt;a href="http://www.hauser-wenz.de/s9y/"&gt;Christian
Wenz&lt;/a&gt; to lend me a hand because he has some PHP experience. He thankfully hosted
an "annotated"&amp;nbsp;version of the PHP script so I could look at the output&amp;nbsp;of
various stages to test my solution with known-good values. That was most helpful.
&lt;/p&gt;
&lt;p&gt;
Instead of doing a Web site demo application with everything intertwined, I split
up the project into two - &lt;strong&gt;GPRDotNet&lt;/strong&gt; being a DLL assembly project
you can reference in any type of .NET application (Windows Forms, Web Forms, you name
it), as well as a simple Web frontend to demo the usage: &lt;strong&gt;DemoSite&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/GooglePageRankInDotNet20.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Querying the page rank is really simple -&amp;nbsp;the following snippet&amp;nbsp;is the code
from the "Check PageRank" button event handler:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; doCheckPageRank_Click(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
EventArgs e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp; GooglePageRank pr &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; GooglePageRank();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp; &lt;/font&gt;string&lt;/span&gt; url &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; webSiteUrl.Text;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp; &lt;/font&gt;try&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;string&lt;/span&gt; rank &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; pr.GetRank(url);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; thePageRank.Text &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; rank;&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp; &lt;/font&gt;catch&lt;/span&gt; (Exception
ex)&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;//
this is rather chatty (telling the end user everything *IS* a bad idea)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; thePageRank.Text &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Requesting
the page rank failed. Reason: "&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; ex.ToString();&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
I want to emphasize that the code for the GooglePageRank class is a rather quick &amp;amp;
dirty port of the PHP code and&amp;nbsp;that it does not contain the necessary error handling
you would expect for a server-side library. After all, it is just a proof of concept
for our community.
&lt;/p&gt;
&lt;p&gt;
Finally, here is the source code: &lt;a href="http://chrison.net/content/binary/PageRank.zip"&gt;PageRank.zip
(26.89 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
If you find errors, please leave a blog comment so others know about improvements.
Thanks!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=ef3e6b4b-9ac4-455b-b784-837646d5e8b4" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,ef3e6b4b-9ac4-455b-b784-837646d5e8b4.aspx</comments>
      <category>.NET</category>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>C#</category>
      <category>Community</category>
      <category>this</category>
      <category>Use the source Luke</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=ee4d8654-3f1b-4151-a12f-81b4f09f6384</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,ee4d8654-3f1b-4151-a12f-81b4f09f6384.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,ee4d8654-3f1b-4151-a12f-81b4f09f6384.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ee4d8654-3f1b-4151-a12f-81b4f09f6384</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Next week, I will be in Rosenheim, Germany for the <a href="http://www.adc2005.de">ADC
2005</a>. I'll be teaching the Visual Studio 2005 Team System Hands-on workshop (Tuesday
as well as Friday), plus doing two talks during the main conference: IIS 7 and ASP.NET
2.0 Health Monitoring. See you there!
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=ee4d8654-3f1b-4151-a12f-81b4f09f6384" />
      </body>
      <title>Next Week: ADC 2005 - Advanced Developers Conference</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,ee4d8654-3f1b-4151-a12f-81b4f09f6384.aspx</guid>
      <link>http://chrison.net/NextWeekADC2005AdvancedDevelopersConference.aspx</link>
      <pubDate>Sun, 27 Nov 2005 22:01:00 GMT</pubDate>
      <description>&lt;p&gt;
Next week, I will be in Rosenheim, Germany for the &lt;a href="http://www.adc2005.de"&gt;ADC
2005&lt;/a&gt;. I'll be teaching the Visual Studio 2005 Team System Hands-on workshop (Tuesday
as well as Friday), plus doing two talks during the main conference: IIS 7 and ASP.NET
2.0 Health Monitoring. See you there!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=ee4d8654-3f1b-4151-a12f-81b4f09f6384" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,ee4d8654-3f1b-4151-a12f-81b4f09f6384.aspx</comments>
      <category>.NET</category>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>IIS</category>
      <category>Project Management</category>
      <category>Team System</category>
      <category>this</category>
      <category>Training and Conferences</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=756ccb94-f23f-4a33-b147-592557a2a133</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,756ccb94-f23f-4a33-b147-592557a2a133.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,756ccb94-f23f-4a33-b147-592557a2a133.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=756ccb94-f23f-4a33-b147-592557a2a133</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
You need: Visual Studio 2005, IIS 6.0 and <a href="http://msdn.microsoft.com/asp.net/reference/infrastructure/wdp/default.aspx">Visual
Studio 2005 Web Deployment Projects (Beta Preview).</a> Of course, the .NET Framework
2.0 should be installed.
</p>
        <p>
The site has one simple page: Convert.aspx (C#, separate code file):
</p>
        <p>
          <img src="http://chrison.net/content/binary/funwithaspnet2compilation1.png" border="0" />
        </p>
        <p>
As you can see, this page is being run with the ASP.NET Development Web Server. Also
works fine with IIS 6.0.
</p>
        <p>
Next, let's add a deployment project to our Web project:
</p>
        <p>
          <img src="http://chrison.net/content/binary/funwithaspnet2compilation5.png" border="0" />
        </p>
        <p>
Build it, and in IIS, create a new application and map it to the Debug directory.
Execute the page:
</p>
        <p>
          <img src="http://chrison.net/content/binary/funwithaspnet2compilation2.png" border="0" />
        </p>
        <p>
Oopsie, what the hell happened here? The answer can be found by digging into the Temporary
ASP.NET Files directory:
</p>
        <p>
          <img src="http://chrison.net/content/binary/funwithaspnet2compilation3.png" border="0" />
        </p>
        <p>
Let's have a look at the generated vs precompiled assemblies in ILDasm:
</p>
        <p>
          <img src="http://chrison.net/content/binary/funwithaspnet2compilation4.png" border="0" />
        </p>
        <p>
So what's the difference? Well, it happens that by default on-demand compilation and
precompilation behave differently in the way the pages (page classes) are stitched
together. In one case we have a quasi-random name, and in the other we have the class
name as it was set in our Convert.aspx - Convert. And this rather obviously clashes
with System.Convert (I have a certain talent on picking about the single problematic
name).
</p>
        <p>
Why is the Convert name retained? Look in Property Tabs for the deployment project:
</p>
        <p>
          <img src="http://chrison.net/content/binary/funwithaspnet2compilation6.png" border="0" />
        </p>
        <p>
By default "Allow this precompiled site to be updatable" is checked - which after
all is very useful. But not in this specific case where my Convert class clashes with
System.Convert...
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=756ccb94-f23f-4a33-b147-592557a2a133" />
      </body>
      <title>Fun with ASP.NET 2.0 Compilation</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,756ccb94-f23f-4a33-b147-592557a2a133.aspx</guid>
      <link>http://chrison.net/FunWithASPNET20Compilation.aspx</link>
      <pubDate>Mon, 14 Nov 2005 13:59:58 GMT</pubDate>
      <description>&lt;p&gt;
You need: Visual Studio 2005, IIS 6.0 and &lt;a href="http://msdn.microsoft.com/asp.net/reference/infrastructure/wdp/default.aspx"&gt;Visual
Studio 2005 Web Deployment Projects (Beta Preview).&lt;/a&gt;&amp;nbsp;Of course, the .NET Framework
2.0 should be installed.
&lt;/p&gt;
&lt;p&gt;
The site has one simple page: Convert.aspx (C#, separate code file):
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/funwithaspnet2compilation1.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see, this page is being run with the ASP.NET Development Web Server. Also
works fine with IIS 6.0.
&lt;/p&gt;
&lt;p&gt;
Next, let's add a deployment project to our Web project:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/funwithaspnet2compilation5.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Build it, and in IIS, create a new application and map it to the Debug directory.
Execute the page:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/funwithaspnet2compilation2.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Oopsie, what the hell happened here? The answer can be found by digging into the Temporary
ASP.NET Files directory:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/funwithaspnet2compilation3.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Let's have a look at the generated vs precompiled assemblies in ILDasm:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/funwithaspnet2compilation4.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
So what's the difference? Well, it happens that by default on-demand compilation and
precompilation behave differently in the way the pages (page classes) are stitched
together. In one case we have a quasi-random name, and in the other we have the class
name as it was set in our Convert.aspx - Convert. And this rather obviously clashes
with System.Convert (I have a certain talent on picking about the single problematic
name).
&lt;/p&gt;
&lt;p&gt;
Why is the Convert name retained? Look in Property Tabs for the deployment project:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/funwithaspnet2compilation6.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
By default "Allow this precompiled site to be updatable" is checked - which after
all is very useful. But not in this specific case where my Convert class clashes with
System.Convert...
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=756ccb94-f23f-4a33-b147-592557a2a133" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,756ccb94-f23f-4a33-b147-592557a2a133.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=7547aba4-1d97-480f-a787-cf6511650f84</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,7547aba4-1d97-480f-a787-cf6511650f84.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,7547aba4-1d97-480f-a787-cf6511650f84.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=7547aba4-1d97-480f-a787-cf6511650f84</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my blog entry <a href="http://chrison.net/CrashingVisualStudio2005ForFun.aspx">Crashing
Visual Studio 2005 for Fun</a> I described how to crash Visual Studio 2005. Scott
Guthrie followed up, and since then I was in permanent contact with team members.
After some research, it turned out that it (a) was seemingly reproducible only on
my machine, and (b) likely a tooltip issue. 
</p>
        <p>
What is going? Well, my machine is equipped with a Matrox P750 and has three monitors
attached, spanning a single 3840x1024 "display". This strechted single display is
managed by Matrox PowerDesk-HF, and it comes with a couple of desktop settings to
make applications play nice on three physical monitors. One of those options is "Prevent
tooltip spanning in strechted mode":
</p>
        <p>
          <img src="http://chrison.net/content/binary/vs05crashupdate1.png" border="0" />
        </p>
        <p>
What does this option do? Imagine that I have an application full screen on the middle
monitor - without that option turned on, tooltips "overflow" to the monitor to the
right (you only see the background image in this screenshot, but that is the 3rd monitor):
</p>
        <p>
          <img src="http://chrison.net/content/binary/vs05crashupdate2.png" border="0" />
        </p>
        <p>
Now guess what - once I turn that option on, VS05 crashes the way I <a href="http://chrison.net/CrashingVisualStudio2005ForFun.aspx">described
in my previous blog entry</a>. It took me a couple of reboots, configuration from
scratch and quite some testing to finally figure out the root cause for this crash.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=7547aba4-1d97-480f-a787-cf6511650f84" />
      </body>
      <title>Issue Identified: Crashing Visual Studio 2005 for Fun</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,7547aba4-1d97-480f-a787-cf6511650f84.aspx</guid>
      <link>http://chrison.net/IssueIdentifiedCrashingVisualStudio2005ForFun.aspx</link>
      <pubDate>Mon, 14 Nov 2005 12:23:40 GMT</pubDate>
      <description>&lt;p&gt;
In my blog entry &lt;a href="http://chrison.net/CrashingVisualStudio2005ForFun.aspx"&gt;Crashing
Visual Studio 2005 for Fun&lt;/a&gt; I described how to crash Visual Studio 2005. Scott
Guthrie followed up, and since then I was in permanent contact with team members.
After some research, it turned out that it (a) was seemingly reproducible only on
my machine, and (b) likely a tooltip issue. 
&lt;/p&gt;
&lt;p&gt;
What is going? Well, my machine is equipped with a Matrox P750 and has three monitors
attached, spanning a single 3840x1024 "display". This strechted single display is
managed by Matrox PowerDesk-HF, and it comes with a couple of desktop settings to
make applications play nice on three physical monitors. One of those options is "Prevent
tooltip spanning in strechted mode":
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/vs05crashupdate1.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
What does this option do? Imagine that I have an application full screen on the middle
monitor - without that option turned on, tooltips "overflow" to the monitor to the
right (you only see the background image in this screenshot, but that is the 3rd monitor):
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/vs05crashupdate2.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Now guess what - once I turn that option on, VS05 crashes the way I &lt;a href="http://chrison.net/CrashingVisualStudio2005ForFun.aspx"&gt;described
in my previous blog entry&lt;/a&gt;. It took me a couple of reboots, configuration from
scratch and quite some testing to finally figure out the root cause for this crash.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=7547aba4-1d97-480f-a787-cf6511650f84" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,7547aba4-1d97-480f-a787-cf6511650f84.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>this</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=93601f8b-3029-449b-b5a6-39048758be9b</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,93601f8b-3029-449b-b5a6-39048758be9b.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,93601f8b-3029-449b-b5a6-39048758be9b.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=93601f8b-3029-449b-b5a6-39048758be9b</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This week I got started and I implemented a <a href="http://chrison.net/ConvertC20CodeToVBNET80.aspx">C#
to VB.NET conversion</a>. Today, I added VB.NET to C#, as well as C# / VB.NET to Boo.
You can find the new converter at this URL:
</p>
        <p>
          <a href="http://developer.sharpdevelop.net/codeconvert.net/">http://developer.sharpdevelop.net/codeconvert.net/</a>
        </p>
        <p>
In addition to the "usual" Web interface, I also added a Web Service. This enables
you to remotely exploit the code conversion features of <a href="http://www.icsharpcode.net/opensource/sd/">#develop</a>.
For example, in a Windows Forms application:
</p>
        <p>
          <img src="http://chrison.net/content/binary/CodeConverter.png" border="0" />
        </p>
        <p>
It behaves exactly the same way as the <a href="http://developer.sharpdevelop.net/codeconvert.net/Convert.aspx">online
converter</a>. To get you started, the following download contains both the executable
(in the bin/release folder) as well as the source code for the application shown in
this screenshot. Have fun, and please don't forget to <a href="http://community.sharpdevelop.net/forums/19/ShowForum.aspx">report
conversion errors</a> so we can improve the underlying <a href="http://laputa.sharpdevelop.net/NRefactoryTutorialVideo.aspx">NRefactory</a>!
</p>
        <p>
          <a href="http://chrison.net/content/binary/CodeConvertServiceClient.zip">CodeConvertServiceClient.zip
(38.57 KB)</a>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=93601f8b-3029-449b-b5a6-39048758be9b" />
      </body>
      <title>Code Converter for .NET 2.0 - Online, as well as Offline</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,93601f8b-3029-449b-b5a6-39048758be9b.aspx</guid>
      <link>http://chrison.net/CodeConverterForNET20OnlineAsWellAsOffline.aspx</link>
      <pubDate>Sun, 13 Nov 2005 20:11:00 GMT</pubDate>
      <description>&lt;p&gt;
This week I got started and I implemented a&amp;nbsp;&lt;a href="http://chrison.net/ConvertC20CodeToVBNET80.aspx"&gt;C#
to VB.NET conversion&lt;/a&gt;. Today, I added VB.NET to C#, as well as C# / VB.NET to Boo.
You can find the new converter at this URL:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://developer.sharpdevelop.net/codeconvert.net/"&gt;http://developer.sharpdevelop.net/codeconvert.net/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
In addition to the "usual" Web interface, I also added a Web Service. This enables
you to remotely exploit the code conversion features of &lt;a href="http://www.icsharpcode.net/opensource/sd/"&gt;#develop&lt;/a&gt;.
For example, in a Windows Forms application:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/CodeConverter.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
It behaves exactly the same way as the &lt;a href="http://developer.sharpdevelop.net/codeconvert.net/Convert.aspx"&gt;online
converter&lt;/a&gt;. To get you started, the following download contains both the executable
(in the bin/release folder) as well as the source code for the application shown in
this screenshot. Have fun, and please don't forget to &lt;a href="http://community.sharpdevelop.net/forums/19/ShowForum.aspx"&gt;report
conversion errors&lt;/a&gt; so we can improve the underlying &lt;a href="http://laputa.sharpdevelop.net/NRefactoryTutorialVideo.aspx"&gt;NRefactory&lt;/a&gt;!
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/CodeConvertServiceClient.zip"&gt;CodeConvertServiceClient.zip
(38.57 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=93601f8b-3029-449b-b5a6-39048758be9b" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,93601f8b-3029-449b-b5a6-39048758be9b.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Cool Download</category>
      <category>Use the source Luke</category>
      <category>Web Services</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=82eaf5e8-bff9-4d5c-821d-d323aca59679</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,82eaf5e8-bff9-4d5c-821d-d323aca59679.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,82eaf5e8-bff9-4d5c-821d-d323aca59679.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=82eaf5e8-bff9-4d5c-821d-d323aca59679</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just finished a Web-based C# to VB.NET converter for .NET 2.0. It took me about
half an hour and 20 lines of code. How come? Well, Daniel (<a href="http://www.icsharpcode.net/opensource/sd/">#develop</a> 2.0
PM) did a <a href="http://laputa.sharpdevelop.net/NRefactoryTutorialVideo.aspx">video
on NRefactory</a>, which is at the heart of #develop's parsing infrastructure. I took
some of his demo code plus some of #develop's internal code converter, and put it
into a ASP.NET 2.0 page. Presto, that easy if you can stand on the shoulders of giants.
</p>
        <p>
Oh, and I actually put it online, here is the link: <a href="http://developer.sharpdevelop.net/codeconvert.net/convertcsharp20tovbnet80.aspx">C#
to VB.NET converter</a> (you can find the source code for a simpler VB.NET implementation
of the converter <a href="http://laputa.sharpdevelop.net/CToVBNETCodeConversionASPNETStyle.aspx">here</a>).
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=82eaf5e8-bff9-4d5c-821d-d323aca59679" />
      </body>
      <title>Convert C# 2.0 Code to VB.NET 8.0</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,82eaf5e8-bff9-4d5c-821d-d323aca59679.aspx</guid>
      <link>http://chrison.net/ConvertC20CodeToVBNET80.aspx</link>
      <pubDate>Thu, 10 Nov 2005 19:22:24 GMT</pubDate>
      <description>&lt;p&gt;
I just finished a Web-based C# to VB.NET converter for .NET 2.0. It took me about
half an hour and 20 lines of code. How come? Well, Daniel (&lt;a href="http://www.icsharpcode.net/opensource/sd/"&gt;#develop&lt;/a&gt; 2.0
PM) did a &lt;a href="http://laputa.sharpdevelop.net/NRefactoryTutorialVideo.aspx"&gt;video
on NRefactory&lt;/a&gt;, which is at the heart of #develop's parsing infrastructure. I took
some of his demo code plus some of #develop's internal code converter, and put it
into a ASP.NET 2.0 page. Presto, that easy if you can stand on the shoulders of giants.
&lt;/p&gt;
&lt;p&gt;
Oh, and I actually put it online, here is the link: &lt;a href="http://developer.sharpdevelop.net/codeconvert.net/convertcsharp20tovbnet80.aspx"&gt;C#
to VB.NET converter&lt;/a&gt;&amp;nbsp;(you can find the source code for a simpler VB.NET implementation
of the converter &lt;a href="http://laputa.sharpdevelop.net/CToVBNETCodeConversionASPNETStyle.aspx"&gt;here&lt;/a&gt;).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=82eaf5e8-bff9-4d5c-821d-d323aca59679" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,82eaf5e8-bff9-4d5c-821d-d323aca59679.aspx</comments>
      <category>.NET</category>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>C#</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=f8218b22-4f34-4814-a22a-fa439393a9d7</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,f8218b22-4f34-4814-a22a-fa439393a9d7.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,f8218b22-4f34-4814-a22a-fa439393a9d7.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=f8218b22-4f34-4814-a22a-fa439393a9d7</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Now, I did not set out to crash it intentionally, but at least it is fully reproducible.
What did I do? Well, I wanted to build a site based on the code I wrote in the blog
entry <a href="http://chrison.net/WritingASubversionbackedVirtualPathProviderForASPNET20.aspx">Writing
a Subversion-backed VirtualPathProvider for ASP.NET 2.0</a>. So I created a new directory
for the site, and simply put the code from the download into a subdirectory (which
already exists in the zip file):
</p>
        <p>
          <img src="http://chrison.net/content/binary/vs05crash1.png" border="0" />
        </p>
        <p>
Of course I went ahead and opened MyNewWebSite in Visual Studio 2005:
</p>
        <p>
          <img src="http://chrison.net/content/binary/vs05crash2.png" border="0" />
        </p>
        <p>
Nothing unexpected so far, I can expand all directories just fine in Solution Explorer:
</p>
        <p>
          <img src="http://chrison.net/content/binary/vs05crash3.png" border="0" />
        </p>
        <p>
However, as soon as I hover over SubversionVirtualPathProvider.cs, Solution Explorer
goes grey. Totally grey. As in no icons, no tree, no nothing. So I File / Exit Visual
Studio 2005 (saying No to saving the solution), and kabooom, here is my friend the
error reporting tool:
</p>
        <p>
          <img src="http://chrison.net/content/binary/vs05crash4.png" border="0" />
        </p>
        <p>
Oh, and btw, an empty App_Code directory won't do the trick.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=f8218b22-4f34-4814-a22a-fa439393a9d7" />
      </body>
      <title>Crashing Visual Studio 2005 for fun</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,f8218b22-4f34-4814-a22a-fa439393a9d7.aspx</guid>
      <link>http://chrison.net/CrashingVisualStudio2005ForFun.aspx</link>
      <pubDate>Tue, 08 Nov 2005 15:23:13 GMT</pubDate>
      <description>&lt;p&gt;
Now, I did not set out to crash it intentionally, but at least it is fully reproducible.
What did I do? Well, I wanted to build a site based on the code I wrote in the blog
entry &lt;a href="http://chrison.net/WritingASubversionbackedVirtualPathProviderForASPNET20.aspx"&gt;Writing
a Subversion-backed VirtualPathProvider for ASP.NET 2.0&lt;/a&gt;. So I created a new directory
for the site, and simply put the code from the download into a subdirectory (which
already exists in the zip file):
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/vs05crash1.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Of course I went ahead and opened MyNewWebSite in Visual Studio 2005:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/vs05crash2.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Nothing unexpected so far, I can expand all directories just fine in Solution Explorer:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/vs05crash3.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
However, as soon as I hover over SubversionVirtualPathProvider.cs, Solution Explorer
goes grey. Totally grey. As in no icons, no tree, no nothing. So I File / Exit Visual
Studio 2005 (saying No to saving the solution), and kabooom, here is my friend the
error reporting tool:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/vs05crash4.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Oh, and btw, an empty App_Code directory won't do the trick.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=f8218b22-4f34-4814-a22a-fa439393a9d7" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,f8218b22-4f34-4814-a22a-fa439393a9d7.aspx</comments>
      <category>.NET</category>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=62e01334-575e-4fd9-911e-a0dec12ae213</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,62e01334-575e-4fd9-911e-a0dec12ae213.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,62e01334-575e-4fd9-911e-a0dec12ae213.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=62e01334-575e-4fd9-911e-a0dec12ae213</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>The </em>
          <a href="http://www.microsoft.com/downloads/details.aspx?familyid=9e33ea25-666c-47fa-ac52-8d04785c4bd2&amp;displaylang=en">
            <em>ASP.NET
2.0 Deployment Guide</em>
          </a>
          <em> is a reference for web hosters who are interested
in adding ASP.NET 2.0 to their existing Windows hosting service. Besides improving
developer productivity, ASP.NET 2.0 also provides benefits for hosted environments,
including support for shutting down inactive applications and locking down rogue applications.
Enhanced health monitoring configuration can be used to set thresholds and severity
levels for monitoring the health of ASP.NET.</em>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=62e01334-575e-4fd9-911e-a0dec12ae213" />
      </body>
      <title>ASP.NET 2.0 Hosting Deployment Guide</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,62e01334-575e-4fd9-911e-a0dec12ae213.aspx</guid>
      <link>http://chrison.net/ASPNET20HostingDeploymentGuide.aspx</link>
      <pubDate>Sun, 16 Oct 2005 11:20:38 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;The &lt;/em&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=9e33ea25-666c-47fa-ac52-8d04785c4bd2&amp;amp;displaylang=en"&gt;&lt;em&gt;ASP.NET
2.0 Deployment Guide&lt;/em&gt;&lt;/a&gt;&lt;em&gt; is a reference for web hosters who are interested
in adding ASP.NET 2.0 to their existing Windows hosting service. Besides improving
developer productivity, ASP.NET 2.0 also provides benefits for hosted environments,
including support for shutting down inactive applications and locking down rogue applications.
Enhanced health monitoring configuration can be used to set thresholds and severity
levels for monitoring the health of ASP.NET.&lt;/em&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=62e01334-575e-4fd9-911e-a0dec12ae213" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,62e01334-575e-4fd9-911e-a0dec12ae213.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=6dcfd59d-0e5b-4312-8034-a2e9375fe514</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,6dcfd59d-0e5b-4312-8034-a2e9375fe514.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,6dcfd59d-0e5b-4312-8034-a2e9375fe514.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=6dcfd59d-0e5b-4312-8034-a2e9375fe514</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
My dedicated server box not only serves Web applications (such as this blog), it also
handles mail for the respective domains. This means I have to deal with spam. Which
on one hand is nice because I can do whatever I please: drop mail based on whatever
criteria I set up, and use whatever filtering software I need.
</p>
        <p>
This is how the <a href="http://www.nospamtoday.com/server/">NoSpamToday! SMTP Proxy</a> found
its way on my box. I simply got tired of maintaining my (rather old) standalone <a href="http://spamassassin.apache.org/">SpamAssassin</a> installation,
and dealing with <a href="http://www.mailenable.com/">MailEnable</a>'s integrated
but not chained RBL / SPF / virus scanning (by not chained I mean that those
filters are evaluated separately, not like SA, where all filters[rules] are weighted
and evaluated as a whole).
</p>
        <p>
Because I only have one box, I had to resort to relocate MailEnable to port 45, so
that NoSpamToday! could listen on 25 and forward to MailEnable if appropriate (*).
I did configure SMTPS previously (port 465 redirected to localhost:45 via <a href="http://www.stunnel.org/">stunnel</a>),
so standard users could deliver their mail directly to MailEnable instead of having
their outgoing mail scanned by the proxy.
</p>
        <p>
But what about my Web applications? Initially, those were sending to localhost directly,
and as such I had a relaying exception set up in MailEnable. This one had to go, obviously.
So how can applications deliver mail to the mail server via the proxy? SMTP authentication
is necessary for this to happen.
</p>
        <p>
But this doesn't solve the whole issue, it opens a can of worms, performance-wise.
The problem is, every single application (Community Server, dasBlog, Gemini, ...)
assumes that your SMTP server listens on port 25. Wrong. That's the proxy. And that's
a problem: all local outgoing email from those applications is scanned by antivirus
and antispam filters. And that's completely wasting CPU resources. As well as adding
to # of addresses accepted by the backend mailserver, driving up the licenses that
would be needed for NoSpamToday! (**).
</p>
        <p>
Call to action: Implement not only SMTP authentication in your applications, but also
make the SMTP server port configurable. I'm guilty as well.
</p>
        <p>
          <strong>(*)</strong>
        </p>
        <p>
          <img src="http://chrison.net/content/binary/nospamtodayadminconfiguration.png" border="0" />
        </p>
        <p>
          <strong>(**)</strong>
        </p>
        <p>
          <img src="http://chrison.net/content/binary/nospamtodayadminstatus.png" border="0" />
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=6dcfd59d-0e5b-4312-8034-a2e9375fe514" />
      </body>
      <title>Web applications and SMTP proxies don't mix well (it seems)</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,6dcfd59d-0e5b-4312-8034-a2e9375fe514.aspx</guid>
      <link>http://chrison.net/WebApplicationsAndSMTPProxiesDontMixWellItSeems.aspx</link>
      <pubDate>Fri, 14 Oct 2005 08:19:33 GMT</pubDate>
      <description>&lt;p&gt;
My dedicated server box not only serves Web applications (such as this blog), it also
handles mail for the respective domains. This means I have to deal with spam. Which
on one hand is nice because I can do whatever I please: drop mail based on whatever
criteria I set up, and use whatever filtering software I need.
&lt;/p&gt;
&lt;p&gt;
This is how the &lt;a href="http://www.nospamtoday.com/server/"&gt;NoSpamToday! SMTP Proxy&lt;/a&gt; found
its way on my box. I simply got tired of maintaining my (rather old) standalone&amp;nbsp;&lt;a href="http://spamassassin.apache.org/"&gt;SpamAssassin&lt;/a&gt; installation,
and dealing with &lt;a href="http://www.mailenable.com/"&gt;MailEnable&lt;/a&gt;'s integrated
but not chained&amp;nbsp;RBL / SPF / virus scanning (by not chained I mean that those
filters are evaluated separately, not like SA, where all filters[rules] are weighted
and evaluated as a whole).
&lt;/p&gt;
&lt;p&gt;
Because I only have one box, I had to resort to relocate MailEnable to port 45, so
that NoSpamToday! could listen on 25 and forward to MailEnable if appropriate (*).
I did configure SMTPS previously (port 465 redirected to localhost:45 via &lt;a href="http://www.stunnel.org/"&gt;stunnel&lt;/a&gt;),
so standard users could deliver their mail directly to MailEnable instead of having
their outgoing mail scanned by the proxy.
&lt;/p&gt;
&lt;p&gt;
But what about my Web applications? Initially, those were sending to localhost directly,
and as such I had a relaying exception set up in MailEnable. This one had to go, obviously.
So how can applications deliver mail to the mail server via the proxy? SMTP authentication
is necessary for this to happen.
&lt;/p&gt;
&lt;p&gt;
But this doesn't solve the whole issue, it opens a can of worms, performance-wise.
The problem is, every single application (Community Server, dasBlog, Gemini, ...)
assumes that your SMTP server listens on port 25. Wrong. That's the proxy. And that's
a problem: all local outgoing email from those applications&amp;nbsp;is scanned by antivirus
and antispam filters. And that's completely wasting CPU resources. As well as adding
to # of addresses accepted by the backend mailserver, driving up the licenses that
would be needed for NoSpamToday! (**).
&lt;/p&gt;
&lt;p&gt;
Call to action: Implement not only SMTP authentication in your applications, but also
make the SMTP server port configurable. I'm guilty as well.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;(*)&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/nospamtodayadminconfiguration.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;(**)&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/nospamtodayadminstatus.png" border=0&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=6dcfd59d-0e5b-4312-8034-a2e9375fe514" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,6dcfd59d-0e5b-4312-8034-a2e9375fe514.aspx</comments>
      <category>Administration</category>
      <category>ASP.NET</category>
      <category>this</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=41648c13-07ca-4cf7-a00f-035c92588177</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,41648c13-07ca-4cf7-a00f-035c92588177.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,41648c13-07ca-4cf7-a00f-035c92588177.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=41648c13-07ca-4cf7-a00f-035c92588177</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
You only have to wait till the others do all the typing: <a href="http://weblogs.asp.net/pwilson/archive/2005/10/05/426689.aspx">Paul</a> and <a href="http://weblogs.asp.net/Plip/archive/2005/10/05/426685.aspx">Plip</a> are
writing about the Web Deployment Projects feature that we were shown today at the
AspInsiders summit. Cool stuff that should be in the hands of everybody by the time VS05
launches.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=41648c13-07ca-4cf7-a00f-035c92588177" />
      </body>
      <title>Web Deployment Projects</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,41648c13-07ca-4cf7-a00f-035c92588177.aspx</guid>
      <link>http://chrison.net/WebDeploymentProjects.aspx</link>
      <pubDate>Wed, 05 Oct 2005 20:13:13 GMT</pubDate>
      <description>&lt;p&gt;
You only have to wait&amp;nbsp;till the others do all the typing: &lt;a href="http://weblogs.asp.net/pwilson/archive/2005/10/05/426689.aspx"&gt;Paul&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/Plip/archive/2005/10/05/426685.aspx"&gt;Plip&lt;/a&gt; are
writing about the Web Deployment Projects feature that we were shown today at the
AspInsiders summit. Cool stuff that should be in the hands of everybody by the time&amp;nbsp;VS05
launches.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=41648c13-07ca-4cf7-a00f-035c92588177" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,41648c13-07ca-4cf7-a00f-035c92588177.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=e7a53005-299e-456e-9af2-40d927045d98</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,e7a53005-299e-456e-9af2-40d927045d98.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,e7a53005-299e-456e-9af2-40d927045d98.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=e7a53005-299e-456e-9af2-40d927045d98</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Rob Howard <a href="http://weblogs.asp.net/rhoward/archive/2005/10/03/426425.aspx">blogs
about this acquisition</a>. Cool things coming to Community Server!
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=e7a53005-299e-456e-9af2-40d927045d98" />
      </body>
      <title>Telligent acquires Dozing Dogs CMS</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,e7a53005-299e-456e-9af2-40d927045d98.aspx</guid>
      <link>http://chrison.net/TelligentAcquiresDozingDogsCMS.aspx</link>
      <pubDate>Mon, 03 Oct 2005 17:51:06 GMT</pubDate>
      <description>&lt;p&gt;
Rob Howard &lt;a href="http://weblogs.asp.net/rhoward/archive/2005/10/03/426425.aspx"&gt;blogs
about this acquisition&lt;/a&gt;. Cool things coming to Community Server!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=e7a53005-299e-456e-9af2-40d927045d98" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,e7a53005-299e-456e-9af2-40d927045d98.aspx</comments>
      <category>ASP.NET</category>
      <category>Community</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=c0389f43-ddbc-4cd6-ae94-0b982164338a</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,c0389f43-ddbc-4cd6-ae94-0b982164338a.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,c0389f43-ddbc-4cd6-ae94-0b982164338a.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=c0389f43-ddbc-4cd6-ae94-0b982164338a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
At the MVP Summit, the EMEA / LATAM ASP.NET MVPs were partnering to prepare feedback
for the team (any more information and I have to shoot you, or shoot your lawyer if
you prefer). We were having a jolly good time (we all agreed to spend money on beer
and... but that's another story). At that point I suggested that we (book authors,
bloggers, article authors, et al) should slap a mandatory warning on our sample code
/ application: "Not built to scale."
</p>
        <p>
However, in the German community we have an application built to scale: <a href="http://codefairway.net/">CodeFairway.NET</a>.
I wrote an <a href="http://chrison.net/WarningLowFlyingGolfBalls.aspx">overview article</a>,
now <a href="http://alexonasp.net">Alex</a> followed up with an in-depth look at the
features, architecture and techniques of CFW. Read <a href="http://blogs.dotnetgerman.com/alexonasp.net/PermaLink,guid,68c2c73c-f9eb-4919-a8e1-1edf38affd8a.aspx">Code
Behind: CodeFairway.NET</a>.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=c0389f43-ddbc-4cd6-ae94-0b982164338a" />
      </body>
      <title>Built to scale</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,c0389f43-ddbc-4cd6-ae94-0b982164338a.aspx</guid>
      <link>http://chrison.net/BuiltToScale.aspx</link>
      <pubDate>Mon, 03 Oct 2005 15:24:41 GMT</pubDate>
      <description>&lt;p&gt;
At the MVP Summit, the EMEA / LATAM ASP.NET MVPs were partnering to prepare feedback
for the team (any more information and I have to shoot you, or shoot your lawyer if
you prefer). We were having a jolly good time (we all agreed to spend money on beer
and... but that's another story). At that point I suggested that we (book authors,
bloggers, article authors, et al) should slap a mandatory warning on our sample code
/ application: "Not built to scale."
&lt;/p&gt;
&lt;p&gt;
However, in the German community we have an application built to scale: &lt;a href="http://codefairway.net/"&gt;CodeFairway.NET&lt;/a&gt;.
I wrote an &lt;a href="http://chrison.net/WarningLowFlyingGolfBalls.aspx"&gt;overview article&lt;/a&gt;,
now &lt;a href="http://alexonasp.net"&gt;Alex&lt;/a&gt; followed up with an in-depth look at the
features, architecture and techniques of CFW. Read &lt;a href="http://blogs.dotnetgerman.com/alexonasp.net/PermaLink,guid,68c2c73c-f9eb-4919-a8e1-1edf38affd8a.aspx"&gt;Code
Behind: CodeFairway.NET&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=c0389f43-ddbc-4cd6-ae94-0b982164338a" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,c0389f43-ddbc-4cd6-ae94-0b982164338a.aspx</comments>
      <category>ASP.NET</category>
      <category>Community</category>
      <category>this</category>
      <category>Web Services</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=2735af34-6730-4cdf-90ec-1a1380d26bf3</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,2735af34-6730-4cdf-90ec-1a1380d26bf3.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,2735af34-6730-4cdf-90ec-1a1380d26bf3.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=2735af34-6730-4cdf-90ec-1a1380d26bf3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I already have one box (the Shuttle XPC) that is running Windows Server Codename Longhorn
Build 5219. Because it wasn't all that much of a hassle when compared to Beta 1 of
Windows Vista, I decided to set up Longhorn on my laptop - and try to work with that
installation for a week, while I am in Seattle for the MVP &amp; AspInsiders summits.
Boy did I end up with an installation marathon...
</p>
        <p>
Lessons learned in this Sunday's "don't try this at home kids" department:
</p>
        <ul>
          <li>
Don't assume that ATI drivers for your IBM X31 will install on Longhorn. They refuse,
making for rather crappy UI performance. By the way, on failing, setup suggests to
install a VGA driver first. 
</li>
          <li>
None of the network adapters were found - neither the onboard LAN, nor the onboard
WLAN. When you peek into Computer Mangement, it is your guess which of the two "Ethernet
Controller" is which. 
</li>
          <li>
Don't only update the driver for one, even if it is the LAN one. Your ISA 2004 client
installation will mysteriously fail. After installing drivers for all LAN equipement,
it just works. 
</li>
          <li>
Minor annoyance: the OS-provided sound driver produces hisses et al. Not too bad,
but annoying if you plan to watch loads of Channel 9 movies. Your guess is correct:
the vendor-provided driver refuses to install. 
</li>
          <li>
No standby. That sucks royally. 
</li>
          <li>
You learned about that in my <a href="http://chrison.net/ErrorsYouDontExpect.aspx">previous
post</a> - no .NET 1.1 for you by default. 
</li>
          <li>
Installing VS can be so much fun, especially if MSXML 6.0 refuses to install as part
of the default install. Doing it separately works so much better. And the "Locate
File" dialog for the VM driver irritated me only for the better part of a minute... 
</li>
          <li>
Before installing the Atlas VSIs, you better start VS at least once. Otherwise the
Atlas installation will fail. Only mildly interesting. 
</li>
          <li>
Do I need to mention that Virtual PC networking doesn't work? That one didn't change
for the better, which will make me dual boot into XP.</li>
        </ul>
        <p>
On a different note: default installs of 5219 have a blank password for Administrator.
And IIS 7 is installed by default, which really baffled me. I'm so trained to enable
features after install that at first I was thinking it was not part of the bits I
got...
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=2735af34-6730-4cdf-90ec-1a1380d26bf3" />
      </body>
      <title>Windows Server Codename Longhorn, Visual Studio 2005 Team System Beta 2, LINQ &amp; Atlas</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,2735af34-6730-4cdf-90ec-1a1380d26bf3.aspx</guid>
      <link>http://chrison.net/WindowsServerCodenameLonghornVisualStudio2005TeamSystemBeta2LINQAtlas.aspx</link>
      <pubDate>Sun, 25 Sep 2005 20:25:57 GMT</pubDate>
      <description>&lt;p&gt;
I already have one box (the Shuttle XPC) that is running Windows Server Codename Longhorn
Build 5219. Because it wasn't all that much of a hassle when compared to Beta 1 of
Windows Vista, I decided to set up Longhorn on my laptop - and try to work with that
installation for a week, while I am in Seattle for the MVP &amp;amp; AspInsiders summits.
Boy did I end up with an installation marathon...
&lt;/p&gt;
&lt;p&gt;
Lessons learned in this Sunday's "don't try this at home kids" department:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Don't assume that ATI drivers for your IBM X31 will install on Longhorn. They refuse,
making for rather crappy UI performance. By the way, on failing, setup suggests to
install a VGA driver first. 
&lt;li&gt;
None of the network adapters were found - neither the onboard LAN, nor the onboard
WLAN. When you peek into Computer Mangement, it is your guess which of the two "Ethernet
Controller" is which. 
&lt;li&gt;
Don't only update the driver for one, even if it is the LAN one. Your ISA 2004 client
installation will mysteriously fail. After installing drivers for&amp;nbsp;all LAN equipement,
it just works. 
&lt;li&gt;
Minor annoyance: the OS-provided sound driver produces hisses et al. Not too bad,
but annoying if you plan to watch loads of Channel 9 movies. Your guess is correct:
the vendor-provided driver refuses to install. 
&lt;li&gt;
No standby. That sucks royally. 
&lt;li&gt;
You learned about that in my &lt;a href="http://chrison.net/ErrorsYouDontExpect.aspx"&gt;previous
post&lt;/a&gt; - no .NET 1.1 for you by default. 
&lt;li&gt;
Installing VS can be so much fun, especially if MSXML 6.0 refuses to install as part
of the default install. Doing it separately works so much better. And the "Locate
File" dialog for the VM driver irritated me only for the better part of a minute... 
&lt;li&gt;
Before installing the Atlas VSIs, you better start VS at least once. Otherwise the
Atlas installation will fail. Only mildly interesting. 
&lt;li&gt;
Do I need to mention that Virtual PC networking doesn't work? That one didn't change
for the better, which will make me dual boot into XP.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
On a different note: default installs of 5219 have a blank password for Administrator.
And IIS 7 is installed by default, which really baffled me. I'm so trained to enable
features after install that at first I was thinking it was not part of the bits I
got...
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=2735af34-6730-4cdf-90ec-1a1380d26bf3" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,2735af34-6730-4cdf-90ec-1a1380d26bf3.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>C#</category>
      <category>IIS</category>
      <category>Longhorn</category>
      <category>Team System</category>
      <category>this</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=c40b666f-e24b-46f0-9d72-91ae04f82992</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,c40b666f-e24b-46f0-9d72-91ae04f82992.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,c40b666f-e24b-46f0-9d72-91ae04f82992.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=c40b666f-e24b-46f0-9d72-91ae04f82992</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <a href="http://www.nikhilk.net/">Nikhil</a> demonstrated
it last week at the PDC, now he released the new version of the <a href="http://www.nikhilk.net/Project.WebDevHelper.aspx">Web
Development Helper</a> to the public. Read more about the exciting new features <a href="http://www.nikhilk.net/Entry.aspx?id=93">here</a>. 
<p></p><img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=c40b666f-e24b-46f0-9d72-91ae04f82992" /></body>
      <title>Debugging Web Applications using Web Development Helper</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,c40b666f-e24b-46f0-9d72-91ae04f82992.aspx</guid>
      <link>http://chrison.net/DebuggingWebApplicationsUsingWebDevelopmentHelper.aspx</link>
      <pubDate>Tue, 20 Sep 2005 09:45:47 GMT</pubDate>
      <description>&lt;a href="http://www.nikhilk.net/"&gt;Nikhil&lt;/a&gt; demonstrated it last week at the PDC,
now he released the new version of the &lt;a href="http://www.nikhilk.net/Project.WebDevHelper.aspx"&gt;Web
Development Helper&lt;/a&gt;&amp;nbsp;to the public. Read more about the exciting new features &lt;a href="http://www.nikhilk.net/Entry.aspx?id=93"&gt;here&lt;/a&gt;. 
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=c40b666f-e24b-46f0-9d72-91ae04f82992" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,c40b666f-e24b-46f0-9d72-91ae04f82992.aspx</comments>
      <category>ASP.NET</category>
      <category>Cool Download</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=4ecdcbc2-0a25-4d73-9c46-9de02a13e643</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,4ecdcbc2-0a25-4d73-9c46-9de02a13e643.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,4ecdcbc2-0a25-4d73-9c46-9de02a13e643.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=4ecdcbc2-0a25-4d73-9c46-9de02a13e643</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The day started out with one of those famous spoof videos - this time about a "variation"
of Windows error reporting, dubbed WE-SYP (we share your pain). Error reporting tied
to a - let's call it - "multimedia" chair. Fun to watch.
</p>
        <p>
Right after that, Bob Muglia showed off what we can expect from Windows Server in
the next couple of year. <a href="http://www.microsoft.com/windowsserver2003/hpc/default.mspx">Windows
Server 2003 Compute Cluster Solution</a> was demoed together with Excel Services -
impressive. TxF (transactional NTFS) wasn't any less exciting, just like the identity
solutions - and, of course, IIS 7.0. We got the bits for the latter today. 
</p>
        <p>
Sessions I attended today:
</p>
        <ul>
          <li>
Windows Communications Foundation ("Indigo"): A Deep Dive into Best Practices Using
the Windows Communications Foundation 
</li>
          <li>
ASP.NET: Future Directions for Developing Rich Web Applications with Atlas (Part 2) 
</li>
          <li>
ASP.NET: A Sneak Peek at Future Directions in Web Development and Designer Tools 
</li>
          <li>
Windows Vista &amp; "Longhorn" Server: Under the Hood of the Operating System—System
Internals and Your Application 
</li>
          <li>
ASP.NET: Deep Dive into the ObjectDataSource Control 
</li>
        </ul>
        <p>
The under the hood session for Longhorn server had one interesting tidbit - they
aim to require mandatory signing for kernel mode drivers on x64 platforms - bye bye kernel
root kits!
</p>
        <p>
Bradley Millington quite overshot his allocated timeslot for the ObjectDataSource
control, but he covered interesting areas: filtering and master details, custom sorting
and paging, updates inserts deletes as well as transactions and caching. Seeing realistic
examples is a welcome change. A good place for you to start: the <a href="http://beta.asp.net/QUICKSTART/aspnet/doc/data/advanced.aspx">Advanced
Data Scenarios</a> section of the <a href="http://beta.asp.net/QUICKSTART/aspnet/default.aspx">Quickstarts</a>.
(Note: those links point to <a href="http://beta.asp.net">http://beta.asp.net</a>,
and I don't think that Whidbey docs will be up and running there forever, given that
"Orcas" starts appearing on the horizon).
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=4ecdcbc2-0a25-4d73-9c46-9de02a13e643" />
      </body>
      <title>PDC05: Day Three, WE-SYP</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,4ecdcbc2-0a25-4d73-9c46-9de02a13e643.aspx</guid>
      <link>http://chrison.net/PDC05DayThreeWESYP.aspx</link>
      <pubDate>Fri, 16 Sep 2005 03:20:36 GMT</pubDate>
      <description>&lt;p&gt;
The day started out with one of those famous spoof videos - this time about a "variation"
of Windows error reporting, dubbed WE-SYP (we share your pain). Error reporting tied
to a - let's call it - "multimedia" chair. Fun to watch.
&lt;/p&gt;
&lt;p&gt;
Right after that, Bob Muglia showed off what we can expect from Windows Server in
the next couple of year. &lt;a href="http://www.microsoft.com/windowsserver2003/hpc/default.mspx"&gt;Windows
Server 2003 Compute Cluster Solution&lt;/a&gt; was demoed together with Excel Services -
impressive. TxF (transactional NTFS) wasn't any less exciting, just like the identity
solutions - and, of course, IIS 7.0. We got the bits&amp;nbsp;for the latter today.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Sessions I attended today:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Windows Communications Foundation ("Indigo"): A Deep Dive into Best Practices Using
the Windows Communications Foundation 
&lt;li&gt;
ASP.NET: Future Directions for Developing Rich Web Applications with Atlas (Part 2) 
&lt;li&gt;
ASP.NET: A Sneak Peek at Future Directions in Web Development and Designer Tools 
&lt;li&gt;
Windows Vista &amp;amp; "Longhorn" Server: Under the Hood of the Operating System—System
Internals and Your Application 
&lt;li&gt;
ASP.NET: Deep Dive into the ObjectDataSource Control 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The under the hood session for Longhorn&amp;nbsp;server had one interesting tidbit - they
aim to require mandatory signing for kernel mode drivers on x64 platforms - bye bye&amp;nbsp;kernel
root kits!
&lt;/p&gt;
&lt;p&gt;
Bradley Millington quite overshot his allocated timeslot for the ObjectDataSource
control, but he covered interesting areas: filtering and master details, custom sorting
and paging, updates inserts deletes as well as transactions and caching. Seeing realistic
examples is a welcome change. A good place for you to start: the &lt;a href="http://beta.asp.net/QUICKSTART/aspnet/doc/data/advanced.aspx"&gt;Advanced
Data Scenarios&lt;/a&gt; section of the &lt;a href="http://beta.asp.net/QUICKSTART/aspnet/default.aspx"&gt;Quickstarts&lt;/a&gt;.
(Note: those links point to &lt;a href="http://beta.asp.net"&gt;http://beta.asp.net&lt;/a&gt;,
and I don't think that Whidbey docs will be up and running there forever, given that
"Orcas" starts appearing on the horizon).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=4ecdcbc2-0a25-4d73-9c46-9de02a13e643" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,4ecdcbc2-0a25-4d73-9c46-9de02a13e643.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>IIS</category>
      <category>Security</category>
      <category>this</category>
      <category>Training and Conferences</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=25c40b62-37eb-42d0-834f-a2067c8ec02d</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,25c40b62-37eb-42d0-834f-a2067c8ec02d.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,25c40b62-37eb-42d0-834f-a2067c8ec02d.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=25c40b62-37eb-42d0-834f-a2067c8ec02d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Want to know what <a href="http://atlas.asp.net/">Atlas</a> is all about? On the <a href="http://atlas.asp.net/">Atlas
site</a> you will find hands-on labs, live quickstarts demoing <a href="http://atlas.asp.net/">Atlas</a> features,
documentation, and VSIs for creating your own <a href="http://atlas.asp.net/">Atlas</a> apps
with Visual Studio 2005. What are you waiting for? Check it out now!
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=25c40b62-37eb-42d0-834f-a2067c8ec02d" />
      </body>
      <title>PDC05: Atlas</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,25c40b62-37eb-42d0-834f-a2067c8ec02d.aspx</guid>
      <link>http://chrison.net/PDC05Atlas.aspx</link>
      <pubDate>Tue, 13 Sep 2005 15:03:41 GMT</pubDate>
      <description>&lt;p&gt;
Want to know what &lt;a href="http://atlas.asp.net/"&gt;Atlas&lt;/a&gt; is all about? On the &lt;a href="http://atlas.asp.net/"&gt;Atlas
site&lt;/a&gt; you will find&amp;nbsp;hands-on labs, live quickstarts demoing &lt;a href="http://atlas.asp.net/"&gt;Atlas&lt;/a&gt; features,
documentation, and VSIs for creating your own &lt;a href="http://atlas.asp.net/"&gt;Atlas&lt;/a&gt; apps
with Visual Studio 2005. What are you waiting for? Check it out now!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=25c40b62-37eb-42d0-834f-a2067c8ec02d" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,25c40b62-37eb-42d0-834f-a2067c8ec02d.aspx</comments>
      <category>ASP.NET</category>
      <category>Newsbites</category>
      <category>Training and Conferences</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=1d0d95ea-aa35-49e1-8c4d-8ea12034de2a</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,1d0d95ea-aa35-49e1-8c4d-8ea12034de2a.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,1d0d95ea-aa35-49e1-8c4d-8ea12034de2a.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=1d0d95ea-aa35-49e1-8c4d-8ea12034de2a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The PDC today officially kicked off with a keynote by Bill Gates. To me, the more
interesting parts came later in Jim Allchins keynote: <a href="http://atlas.asp.net">Atlas</a>,
Windows Communication Foundation, Windows Presentation Foundation as well as <a href="http://msdn.microsoft.com/netframework/future/">C#
3.0 &amp; LINQ</a>. However, Office 12 does look very promising too. Can't wait to
get my hands on that beta (never expected to say that about Office, ever).
</p>
        <p>
In the afternoon, I attended the following breakouts:
</p>
        <ul>
          <li>
Behind the Scenes of Visual Studio 2005 Team Foundation Server</li>
          <li>
Windows Server “Longhorn”: What's New for Developers</li>
          <li>
Windows Presentation Foundation ("Avalon"): A Lap around the Windows Presentation
Foundation</li>
        </ul>
        <p>
Looking forward to tomorrow, because Windows Workflow Foundation will be revealed
at the keynote (aka general session).
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=1d0d95ea-aa35-49e1-8c4d-8ea12034de2a" />
      </body>
      <title>PDC05: Day One in Review</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,1d0d95ea-aa35-49e1-8c4d-8ea12034de2a.aspx</guid>
      <link>http://chrison.net/PDC05DayOneInReview.aspx</link>
      <pubDate>Tue, 13 Sep 2005 02:33:11 GMT</pubDate>
      <description>&lt;p&gt;
The PDC today officially kicked off with a keynote by Bill Gates. To me, the more
interesting parts came later in Jim Allchins keynote: &lt;a href="http://atlas.asp.net"&gt;Atlas&lt;/a&gt;,
Windows Communication Foundation, Windows Presentation Foundation as well as &lt;a href="http://msdn.microsoft.com/netframework/future/"&gt;C#
3.0 &amp;amp; LINQ&lt;/a&gt;. However, Office 12 does look very promising too. Can't wait to
get my hands on that beta (never expected to say that about Office, ever).
&lt;/p&gt;
&lt;p&gt;
In the afternoon, I attended the following breakouts:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Behind the Scenes of Visual Studio 2005 Team Foundation Server&lt;/li&gt;
&lt;li&gt;
Windows Server “Longhorn”: What's New for Developers&lt;/li&gt;
&lt;li&gt;
Windows Presentation Foundation ("Avalon"): A Lap around the Windows Presentation
Foundation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Looking forward to tomorrow, because Windows Workflow Foundation will be revealed
at the keynote (aka general session).
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=1d0d95ea-aa35-49e1-8c4d-8ea12034de2a" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,1d0d95ea-aa35-49e1-8c4d-8ea12034de2a.aspx</comments>
      <category>.NET</category>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>C#</category>
      <category>Team System</category>
      <category>this</category>
      <category>Training and Conferences</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=da83fd2f-45cd-4a1f-b077-1c45bf71dd15</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,da83fd2f-45cd-4a1f-b077-1c45bf71dd15.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,da83fd2f-45cd-4a1f-b077-1c45bf71dd15.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=da83fd2f-45cd-4a1f-b077-1c45bf71dd15</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
From the summary of this security practice: <em>This module presents a set of consolidated
practices designed to address ASP.NET version 2.0 security issues. The answers and
recommendations presented in this module are tight distillations designed to supplement
the companion modules and additional guidance. The practices are organized by various
categories that represent those areas where mistakes are most often made.</em></p>
        <p>
          <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/PAGPractices0001.asp">Security
Practices: ASP.NET 2.0 Security Practices at a Glance</a>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=da83fd2f-45cd-4a1f-b077-1c45bf71dd15" />
      </body>
      <title>ASP.NET 2.0 Security Practices at a Glance</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,da83fd2f-45cd-4a1f-b077-1c45bf71dd15.aspx</guid>
      <link>http://chrison.net/ASPNET20SecurityPracticesAtAGlance.aspx</link>
      <pubDate>Tue, 16 Aug 2005 08:01:40 GMT</pubDate>
      <description>&lt;p&gt;
From the summary of this security practice: &lt;em&gt;This module presents a set of consolidated
practices designed to address ASP.NET version 2.0 security issues. The answers and
recommendations presented in this module are tight distillations designed to supplement
the companion modules and additional guidance. The practices are organized by various
categories that represent those areas where mistakes are most often made.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/PAGPractices0001.asp"&gt;Security
Practices: ASP.NET 2.0 Security Practices at a Glance&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=da83fd2f-45cd-4a1f-b077-1c45bf71dd15" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,da83fd2f-45cd-4a1f-b077-1c45bf71dd15.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Security</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=5a59b248-9afc-49b9-809e-cb258720b4f9</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,5a59b248-9afc-49b9-809e-cb258720b4f9.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,5a59b248-9afc-49b9-809e-cb258720b4f9.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=5a59b248-9afc-49b9-809e-cb258720b4f9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Want to test your Web site with that other browser? You know, the one that ships with
the operating system? Here is how to do that. Start by right-clicking on the page
you want to open:
</p>
        <p>
          <img src="http://chrison.net/content/binary/BrowseWithInVsNet051.png" border="0" />
        </p>
        <p>
In the Browse With dialog box, you can now choose which browser to use this time only,
or by clicking Set as Default, use it for all your future Ctrl+F5 endeavours:
</p>
        <p>
          <img src="http://chrison.net/content/binary/BrowseWithInVsNet052.png" border="0" />
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=5a59b248-9afc-49b9-809e-cb258720b4f9" />
      </body>
      <title>Browse with... in Visual Studio 2005</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,5a59b248-9afc-49b9-809e-cb258720b4f9.aspx</guid>
      <link>http://chrison.net/BrowseWithInVisualStudio2005.aspx</link>
      <pubDate>Wed, 10 Aug 2005 12:37:17 GMT</pubDate>
      <description>&lt;p&gt;
Want to test your Web site with that other browser? You know, the one that ships with
the operating system? Here is how to do that. Start by right-clicking on the page
you want to open:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/BrowseWithInVsNet051.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
In the Browse With dialog box, you can now choose which browser to use this time only,
or by clicking Set as Default, use it for all your future Ctrl+F5 endeavours:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/BrowseWithInVsNet052.png" border=0&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=5a59b248-9afc-49b9-809e-cb258720b4f9" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,5a59b248-9afc-49b9-809e-cb258720b4f9.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=774233cb-8d4f-4956-ab23-b5530130ead2</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,774233cb-8d4f-4956-ab23-b5530130ead2.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,774233cb-8d4f-4956-ab23-b5530130ead2.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=774233cb-8d4f-4956-ab23-b5530130ead2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Sometimes, it might be handy to not have VS.NET pick a dynamic port each and every
time it starts Visual Web Developer Web Server (aka ASP.NET Development Server or,
as it was called back in the old days, Cassini). There is an easy way to get a fixed
port when you press Ctrl+F5. First step is to select the Web project in Solution Explorer:
</p>
        <p>
          <img src="http://chrison.net/content/binary/SettingVisualWebDeveloperWebServerPortNo1.png" border="0" />
        </p>
        <p>
Next, go to the Properties window (DO NOT right-click and choose Property Pages -
you will end up somewhere entirely different):
</p>
        <p>
          <img src="http://chrison.net/content/binary/SettingVisualWebDeveloperWebServerPortNo2.png" border="0" />
        </p>
        <p>
As you can see, I already switched "Use dynamic ports" to False, and in this case,
I chose to stick with the default provided port number. When is this port-setting
useful? When you automate tests, for example.
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=774233cb-8d4f-4956-ab23-b5530130ead2" />
      </body>
      <title>Setting the port for the Visual Web Developer Web Server</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,774233cb-8d4f-4956-ab23-b5530130ead2.aspx</guid>
      <link>http://chrison.net/SettingThePortForTheVisualWebDeveloperWebServer.aspx</link>
      <pubDate>Wed, 10 Aug 2005 12:27:43 GMT</pubDate>
      <description>&lt;p&gt;
Sometimes, it might be handy to not have VS.NET pick a dynamic port each and every
time it starts Visual Web Developer Web Server (aka ASP.NET Development Server or,
as it was called back in the old days, Cassini). There is an easy way to get a fixed
port when you press Ctrl+F5. First step is to select the Web project in Solution Explorer:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/SettingVisualWebDeveloperWebServerPortNo1.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Next, go to the Properties window (DO NOT right-click and choose Property Pages -
you will end up somewhere entirely different):
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/SettingVisualWebDeveloperWebServerPortNo2.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see, I already switched "Use dynamic ports" to False, and in this case,
I chose to stick with the default provided port number. When is this port-setting
useful? When you automate tests, for example.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=774233cb-8d4f-4956-ab23-b5530130ead2" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,774233cb-8d4f-4956-ab23-b5530130ead2.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=98d7149a-d4ab-417e-8df8-f9a4f0807f29</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,98d7149a-d4ab-417e-8df8-f9a4f0807f29.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,98d7149a-d4ab-417e-8df8-f9a4f0807f29.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=98d7149a-d4ab-417e-8df8-f9a4f0807f29</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">Go <a href="http://msdn.microsoft.com/asp.net/community/events/teched2005/default.aspx">here</a>,
and download samples, slides, and for almost all sessions, actually watch it! Especially
interesting might be this one here: <a href="http://msdn.microsoft.com/asp.net/community/events/teched2005/videos/WEB340.htm">WEB340
IIS7: Discover and Move to the Next Generation Web Application Server Platform</a>.<img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=98d7149a-d4ab-417e-8df8-f9a4f0807f29" /></body>
      <title>Watch the ASP.NET 2.0 Presentations from TechEd 2005</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,98d7149a-d4ab-417e-8df8-f9a4f0807f29.aspx</guid>
      <link>http://chrison.net/WatchTheASPNET20PresentationsFromTechEd2005.aspx</link>
      <pubDate>Mon, 08 Aug 2005 17:02:29 GMT</pubDate>
      <description>Go &lt;a href="http://msdn.microsoft.com/asp.net/community/events/teched2005/default.aspx"&gt;here&lt;/a&gt;,
and download samples, slides, and for almost all sessions, actually watch it! Especially
interesting might be this one here: &lt;a href="http://msdn.microsoft.com/asp.net/community/events/teched2005/videos/WEB340.htm"&gt;WEB340
IIS7: Discover and Move to the Next Generation Web Application Server Platform&lt;/a&gt;.&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=98d7149a-d4ab-417e-8df8-f9a4f0807f29" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,98d7149a-d4ab-417e-8df8-f9a4f0807f29.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Cool Download</category>
      <category>Training and Conferences</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=8ce03a01-aefd-4e37-8a11-c924b8f134b7</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,8ce03a01-aefd-4e37-8a11-c924b8f134b7.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,8ce03a01-aefd-4e37-8a11-c924b8f134b7.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=8ce03a01-aefd-4e37-8a11-c924b8f134b7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">Scott Guthrie has written a <a href="http://weblogs.asp.net/scottgu/archive/2005/08/02/421405.aspx">blog
entry</a> about how to make this happen. Really, really easy to do.<img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=8ce03a01-aefd-4e37-8a11-c924b8f134b7" /></body>
      <title>Using Custom Attributes in the @Page Directive</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,8ce03a01-aefd-4e37-8a11-c924b8f134b7.aspx</guid>
      <link>http://chrison.net/UsingCustomAttributesInThePageDirective.aspx</link>
      <pubDate>Wed, 03 Aug 2005 07:50:14 GMT</pubDate>
      <description>Scott Guthrie has written&amp;nbsp;a &lt;a href="http://weblogs.asp.net/scottgu/archive/2005/08/02/421405.aspx"&gt;blog
entry&lt;/a&gt; about how to make this happen. Really, really easy to do.&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=8ce03a01-aefd-4e37-8a11-c924b8f134b7" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,8ce03a01-aefd-4e37-8a11-c924b8f134b7.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=9a03c7a7-aac7-46dd-881c-bda83b5afbe2</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,9a03c7a7-aac7-46dd-881c-bda83b5afbe2.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,9a03c7a7-aac7-46dd-881c-bda83b5afbe2.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=9a03c7a7-aac7-46dd-881c-bda83b5afbe2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">The Microsoft ASP.NET Developer Center
has the <a href="http://msdn.microsoft.com/asp.net/beta2/providers/default.aspx">Provider
Toolkit</a> online. It sports the Access Provider as a C# class library project for
download!<img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=9a03c7a7-aac7-46dd-881c-bda83b5afbe2" /></body>
      <title>Provider Toolkit</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,9a03c7a7-aac7-46dd-881c-bda83b5afbe2.aspx</guid>
      <link>http://chrison.net/ProviderToolkit.aspx</link>
      <pubDate>Tue, 02 Aug 2005 09:46:18 GMT</pubDate>
      <description>The Microsoft ASP.NET Developer Center has the &lt;a href="http://msdn.microsoft.com/asp.net/beta2/providers/default.aspx"&gt;Provider
Toolkit&lt;/a&gt; online. It sports the Access Provider as a C# class library project for
download!&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=9a03c7a7-aac7-46dd-881c-bda83b5afbe2" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,9a03c7a7-aac7-46dd-881c-bda83b5afbe2.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Cool Download</category>
      <category>Use the source Luke</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=8022d2fe-820e-496c-b982-86ebde4f7a3c</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,8022d2fe-820e-496c-b982-86ebde4f7a3c.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,8022d2fe-820e-496c-b982-86ebde4f7a3c.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=8022d2fe-820e-496c-b982-86ebde4f7a3c</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One thing I didn't get around to demo at last week's <a href="http://www.dotnetgerman.com/community/cbc05/">CBC05</a> is
the usage of profiles to remember and subsequently set the culture on ASP.NET
pages. That's why I am documenting it now.
</p>
        <p>
To get started, we need to have a profile that stores the user's preferred culture.
So your profile in web.config looks could like this:
</p>
        <pre>    &lt;profile enabled="true" defaultProvider="myProfile"&gt;<br />
      &lt;providers&gt;<br />
        &lt;add name="myProfile"<br />
          type="System.Web.Profile.SqlProfileProvider"<br />
          connectionStringName="NWConn"/&gt;<br />
      &lt;/providers&gt;<br />
      &lt;properties&gt;<br />
        &lt;add name="Culture" type="String" defaultValue="en-US"
/&gt;<br />
        &lt;add name="Theme" type="String" /&gt;<br />
      &lt;/properties&gt;<br />
    &lt;/profile&gt;</pre>
        <p>
The <em>Culture</em> profile setting is changed via a simple (hard-coded) dropdown
list in default.aspx, which also displays a greeting pulled from a localized global
resource, the culture code for verification purposes, as well as the current time
formatted according to the respective locale:
</p>
        <p>
          <img src="http://chrison.net/content/binary/cbc05moduleforcultureselection.png" border="0" />
        </p>
        <p>
The code for the button in default.aspx.cs is rather basic as you would have expected:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">protected</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Button1_Click(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
EventArgs e)<br />
{<br />
   Profile.Culture <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> DropDownList1.SelectedValue;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
// really nasty redirect to go back to this back and see the effect</span><br />
   Response.Redirect(Request.Path <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"?"</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> Server.UrlEncode(DateTime.Now.ToLongTimeString()));<br />
}</span>
        </p>
        <p>
The real magic for setting the culture so that formatting is done correctly, as well
as the right resources being displayed, is done in a custom HttpModule, which needs
to be registered in web.config:
</p>
        <pre>    &lt;httpModules&gt;<br />
      &lt;add name="myProfileModule" type="ICSharpCode.Web.ApplyProfileToPageModule"
/&gt;<br />
    &lt;/httpModules&gt;</pre>
        <p>
This guy lives in App_Code\ApplyProfileToPageModule.cs, and looks like this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Configuration;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.Security;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.UI;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.UI.WebControls;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.UI.HtmlControls;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Threading;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Globalization;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">namespace</span> ICSharpCode.Web<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> ApplyProfileToPageModule
: IHttpModule<br />
 {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> 
public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Dispose()<br />
  {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
// currently, does nothing</span><br />
  }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> 
public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Init(HttpApplication
context)<br />
  {<br />
    context.PreRequestHandlerExecute += AppPreRequestHandlerExecute;<br />
  }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> 
private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> AppPreRequestHandlerExecute(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
EventArgs e)<br />
  {<br />
   Page p <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> HttpContext.Current.Handler <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">as</span> Page;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">   </font>if</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span> !<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> p)<br />
   {<br />
      ProfileCommon pc <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> (ProfileCommon)HttpContext.Current.Profile;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">      </font>string</span> cultureName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> pc.Culture;<br /><br />
      CultureInfo culture <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> CultureInfo(cultureName);<br /><br />
      Thread.CurrentThread.CurrentUICulture <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> culture;<br />
      Thread.CurrentThread.CurrentCulture <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> culture;<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">      </font>//
You can set the Theme exactly the same way, shown below:</span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">      </font>//
p.Theme = pc.Theme;</span><br />
   }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>}<br />
 }<br />
}<br /></span>
        </p>
        <p>
In PreRequestHandlerExecute, I can access the profile, and go ahead and read the culture
that is defined. Then all you need to do is set the CurrentUICulture as well as CurrentCulture
of the CurrentThread. Done.
</p>
        <p>
By the way, this event is also your ticket to set the Theme for a Page - if you have
defined the user's preferred theme in her profile. Neat way of doing this.
</p>
        <p>
          <a href="http://chrison.net/content/binary/LocalizationModule.zip">LocalizationModule.zip
(6.09 KB)</a>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=8022d2fe-820e-496c-b982-86ebde4f7a3c" />
      </body>
      <title>Localization and the ASP.NET 2.0 Profile</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,8022d2fe-820e-496c-b982-86ebde4f7a3c.aspx</guid>
      <link>http://chrison.net/LocalizationAndTheASPNET20Profile.aspx</link>
      <pubDate>Fri, 29 Jul 2005 09:00:03 GMT</pubDate>
      <description>&lt;p&gt;
One thing I didn't get around to demo at last week's &lt;a href="http://www.dotnetgerman.com/community/cbc05/"&gt;CBC05&lt;/a&gt; is
the usage of profiles to remember and subsequently&amp;nbsp;set the culture on ASP.NET
pages. That's why I am documenting it now.
&lt;/p&gt;
&lt;p&gt;
To get started, we need to have a profile that stores the user's preferred culture.
So your profile in web.config looks could like this:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;profile enabled="true" defaultProvider="myProfile"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;providers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="myProfile"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; type="System.Web.Profile.SqlProfileProvider"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connectionStringName="NWConn"/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/providers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;properties&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="Culture" type="String" defaultValue="en-US"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="Theme" type="String" /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/properties&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/profile&amp;gt;&lt;/pre&gt;
&lt;p&gt;
The &lt;em&gt;Culture&lt;/em&gt; profile setting is changed via a simple (hard-coded) dropdown
list in default.aspx, which also displays a greeting pulled from a localized global
resource, the culture code for verification purposes, as well as the current time
formatted according to the respective locale:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/cbc05moduleforcultureselection.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
The code for the button in default.aspx.cs is rather basic as you would have expected:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Button1_Click(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
EventArgs e)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp; Profile.Culture &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; DropDownList1.SelectedValue;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
// really nasty redirect to go back to this back and see the effect&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; Response.Redirect(Request.Path &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"?"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; Server.UrlEncode(DateTime.Now.ToLongTimeString()));&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
The real magic for setting the culture so that formatting is done correctly, as well
as the right resources being displayed, is done in a custom HttpModule, which needs
to be registered in web.config:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;httpModules&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="myProfileModule" type="ICSharpCode.Web.ApplyProfileToPageModule"
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/httpModules&amp;gt;&lt;/pre&gt;
&lt;p&gt;
This guy lives in App_Code\ApplyProfileToPageModule.cs, and looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Configuration;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.Security;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.UI;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.UI.WebControls;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.UI.HtmlControls;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Threading;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Globalization;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt; ICSharpCode.Web&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; ApplyProfileToPageModule
: IHttpModule&lt;br&gt;
&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Dispose()&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
// currently, does nothing&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Init(HttpApplication
context)&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; context.PreRequestHandlerExecute += AppPreRequestHandlerExecute;&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; AppPreRequestHandlerExecute(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
EventArgs e)&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp; Page p &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; HttpContext.Current.Handler &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;as&lt;/span&gt; Page;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;if&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt; !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; p)&lt;br&gt;
&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProfileCommon pc &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; (ProfileCommon)HttpContext.Current.Profile;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;string&lt;/span&gt; cultureName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; pc.Culture;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CultureInfo culture &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; CultureInfo(cultureName);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.CurrentThread.CurrentUICulture &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; culture;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.CurrentThread.CurrentCulture &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; culture;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;//
You can set the Theme exactly the same way, shown below:&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;//
p.Theme = pc.Theme;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
In PreRequestHandlerExecute, I can access the profile, and go ahead and read the culture
that is defined. Then all you need to do is set the CurrentUICulture as well as CurrentCulture
of the CurrentThread. Done.
&lt;/p&gt;
&lt;p&gt;
By the way, this event is also your ticket to set the Theme for a Page - if you have
defined the user's preferred theme in her profile. Neat way of doing this.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/LocalizationModule.zip"&gt;LocalizationModule.zip
(6.09 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=8022d2fe-820e-496c-b982-86ebde4f7a3c" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,8022d2fe-820e-496c-b982-86ebde4f7a3c.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=483d8389-6f52-4f5e-9ba7-c22b0341944a</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,483d8389-6f52-4f5e-9ba7-c22b0341944a.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,483d8389-6f52-4f5e-9ba7-c22b0341944a.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=483d8389-6f52-4f5e-9ba7-c22b0341944a</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Did you know that the Membership API isn't limited to being used inside ASP.NET 2.0
applications? That you can also use it in say a Console application? This is actually
very useful, because that spells automated administration for me.
</p>
        <p>
In order to demo this, I set out and created a very simple Web application that
lists users registered with the Membership system:
</p>
        <p>
          <img src="http://chrison.net/content/binary/cbc05membership01.png" border="0" />
        </p>
        <p>
This simply calls <em>Membership.GetAllUsers()</em> and we are set. More interesting
is web.config (partial view):
</p>
        <pre>  &lt;connectionStrings&gt;<br />
    &lt;add name="NWConn" 
<br />
connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/&gt;<br />
  &lt;/connectionStrings&gt;</pre>
        <pre>  &lt;system.web&gt;<br />
    &lt;membership defaultProvider="myMembership"&gt;<br />
      &lt;providers&gt;<br />
        &lt;clear/&gt;<br />
        &lt;add name="myMembership"<br />
          applicationName="DemoApp" 
<br />
          connectionStringName="NWConn"<br />
          type="System.Web.Security.SqlMembershipProvider,
System.Web, Version=2.0.0.0, ..." /&gt;<br />
      &lt;/providers&gt;<br />
    &lt;/membership&gt;</pre>
        <p>
This is using the stock <em>SqlMembershipProvider</em>, and stores data inside
the Northwind database. Pretty vanilla, except for one important attribute: <strong>applicationName</strong>.
Because one Membership database can hold accounts for multiple applications, we need
to define the name here unless we want to end up with guessing that name for the console
application.
</p>
        <p>
Now let's switch to the Console application. It obviously needs to reference
System.Web.dll:
</p>
        <p>
          <img src="http://chrison.net/content/binary/cbc05membership02.png" border="0" />
        </p>
        <p>
Secondly, it needs an App.Config file (this time, in full glory):
</p>
        <pre>&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />
&lt;configuration&gt;<br />
  &lt;connectionStrings&gt;<br />
    &lt;add 
<br />
      name="NWConn" connectionString="Data Source=cbc05vpc\cbc05;Initial
Catalog=Northwind;User=sa;Password=P@ssw0rd"/&gt;<br />
  &lt;/connectionStrings&gt;</pre>
        <pre>  &lt;system.web&gt;<br />
    &lt;membership defaultProvider="myMembership"&gt;<br />
      &lt;providers&gt;<br />
        &lt;clear/&gt;<br />
        &lt;add name="myMembership"<br />
           applicationName="DemoApp" 
<br />
           connectionStringName="NWConn"<br />
           type="System.Web.Security.SqlMembershipProvider,
System.Web, ..." /&gt;<br />
      &lt;/providers&gt;<br />
    &lt;/membership&gt;<br />
  &lt;/system.web&gt;<br />
&lt;/configuration&gt;</pre>
        <p>
As you can see, I simply copied its contents verbatim from the previously shown web.config.
All we now need is to access the Membership API inside our application:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Collections.Generic;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Text;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.Security;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">namespace</span> TheConsoleApp<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> class</span> Program<br />
 {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Main(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
args)<br />
   {<br />
     MembershipUserCollection muc <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Membership.GetAllUsers();<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
 foreach</span> (MembershipUser mu <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> muc)<br />
      Console.WriteLine(mu.UserName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"
"</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> mu.Email);<br />
   }<br />
 }<br />
}<br /></span>
        </p>
        <p>
Surprise, surprise - it works as expected:
</p>
        <p>
          <img src="http://chrison.net/content/binary/cbc05membership03.png" border="0" />
        </p>
        <p>
Done.
</p>
        <p>
          <a href="http://chrison.net/content/binary/MembershipEverywhere.zip">MembershipEverywhere.zip
(19.28 KB)</a>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=483d8389-6f52-4f5e-9ba7-c22b0341944a" />
      </body>
      <title>Membership Everywhere</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,483d8389-6f52-4f5e-9ba7-c22b0341944a.aspx</guid>
      <link>http://chrison.net/MembershipEverywhere.aspx</link>
      <pubDate>Thu, 28 Jul 2005 12:27:21 GMT</pubDate>
      <description>&lt;p&gt;
Did you know that the Membership API isn't limited to being used inside ASP.NET 2.0
applications? That you can also use it in say a Console application? This is actually
very useful, because that spells automated administration for me.
&lt;/p&gt;
&lt;p&gt;
In order&amp;nbsp;to demo this, I set out and created a very simple Web application that
lists users registered with the Membership system:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/cbc05membership01.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
This simply calls &lt;em&gt;Membership.GetAllUsers()&lt;/em&gt; and we are set. More interesting
is web.config (partial view):
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp; &amp;lt;connectionStrings&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="NWConn" 
&lt;br&gt;
connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/connectionStrings&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp; &amp;lt;system.web&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;membership defaultProvider="myMembership"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;providers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;clear/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="myMembership"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; applicationName="DemoApp" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connectionStringName="NWConn"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; type="System.Web.Security.SqlMembershipProvider,
System.Web, Version=2.0.0.0, ..." /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/providers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/membership&amp;gt;&lt;/pre&gt;
&lt;p&gt;
This is using the stock&amp;nbsp;&lt;em&gt;SqlMembershipProvider&lt;/em&gt;, and stores data inside
the Northwind database. Pretty vanilla, except for one important attribute: &lt;strong&gt;applicationName&lt;/strong&gt;.
Because one Membership database can hold accounts for multiple applications, we need
to define the name here unless we want to end up with guessing that name for the console
application.
&lt;/p&gt;
&lt;p&gt;
Now let's switch to the Console application. It&amp;nbsp;obviously needs to reference
System.Web.dll:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/cbc05membership02.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Secondly, it needs an App.Config file (this time, in full glory):
&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;&lt;br&gt;
&amp;lt;configuration&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;connectionStrings&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name="NWConn" connectionString="Data Source=cbc05vpc\cbc05;Initial
Catalog=Northwind;User=sa;Password=P@ssw0rd"/&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/connectionStrings&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp; &amp;lt;system.web&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;membership defaultProvider="myMembership"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;providers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;clear/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="myMembership"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; applicationName="DemoApp" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; connectionStringName="NWConn"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; type="System.Web.Security.SqlMembershipProvider,
System.Web, ..." /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/providers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/membership&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/system.web&amp;gt;&lt;br&gt;
&amp;lt;/configuration&amp;gt;&lt;/pre&gt;
&lt;p&gt;
As you can see, I simply copied its contents verbatim from the&amp;nbsp;previously shown&amp;nbsp;web.config.
All we now need is to access the Membership API inside our application:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Text;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.Security;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt; TheConsoleApp&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;class&lt;/span&gt; Program&lt;br&gt;
&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Main(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
args)&lt;br&gt;
&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MembershipUserCollection muc &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Membership.GetAllUsers();&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;foreach&lt;/span&gt; (MembershipUser mu &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; muc)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(mu.UserName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"
"&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; mu.Email);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Surprise, surprise - it works as expected:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/cbc05membership03.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Done.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/MembershipEverywhere.zip"&gt;MembershipEverywhere.zip
(19.28 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=483d8389-6f52-4f5e-9ba7-c22b0341944a" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,483d8389-6f52-4f5e-9ba7-c22b0341944a.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=30b39cc2-8175-4b20-938d-60148fcea6de</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,30b39cc2-8175-4b20-938d-60148fcea6de.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,30b39cc2-8175-4b20-938d-60148fcea6de.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=30b39cc2-8175-4b20-938d-60148fcea6de</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This post is again motivated by last week's Community Bootcamp on ASP.NET 2.0, the <a href="http://www.dotnetgerman.com/community/cbc05/">CBC05</a>.
I presented "Under the Covers - Exploring Internals, Page Lifecycle and the Compilation
Mode" from TechEd, using the samples that Simon Calvert provided me with (special
thanks fly out to Simon, Ben Miller and Rich Ersek @MS for providing us with material
- I know I can be a royal pain in the posterior... sometimes at least). 
</p>
        <p>
The talk included a demo of a database-backed virtual path provider (files don't come
from the file system but a database, dynamically). Somehow we started talking about
how cool it would be if you could test your Web sites without checking them out
from source control in the first place - by simply writing a virtual path provider
that goes to the repository on demand. I wrote that idea down.
</p>
        <p>
Actually, I didn't think I'd get around to doing that. But yesterday I decided to
pester one of my devs on the <a href="http://www.icsharpcode.net/OpenSource/SD/Default.aspx">#develop</a> project,
namely <a href="http://wiki.sharpdevelop.net/default.aspx/SharpDevelop.DanielGrunwald">Daniel
Grunwald</a>. He has implemented the <a href="http://subversion.tigris.org">Subversion</a> addin
for our 2.0 version, so he had experience with NSvn, the managed API for talking to
Subversion. I sent a stripped down version of the vpath provider to him, and asked
him to replace database code with NSvn code where appropriate.
</p>
        <p>
It didn't take long, and I had a command-line verified version back, and all I had
to do was make sure that it works with ASP.NET 2.0. There were a few problems I ran
into (like Subversion is case-sensitive and I didn't want that for the Web scenario).
Some of the issues arose simply because client and Web developers have different backgrounds.
Talk about path separators. Or directories where you have to drop assemblies.
</p>
        <p>
Now, let's stop talking, let's take a look at the provider in action:
</p>
        <p>
          <a href="http://chrison.net/content/binary/SvnVPathProvider.wmv">SvnVPathProvider.wmv
(3.76 MB)</a>
        </p>
        <p>
Want to get your hands on that DemoSiteSvn directory with the current rendition of
the SubversionVirtualPathProvider? No problem, just a couple of notes up front on
what you should be aware of:
</p>
        <ul>
          <li>
Only file names are currently treated specially for casing. Ie directories still do
react in a case sensitive way. 
</li>
          <li>
The file name cracking code needs to be reviewed. Currently, this is a quick hack. 
</li>
          <li>
appSettings need to be placed in a separate .config file. Reason is that web.config
cannot be obtained via a VirtualPathProvider, and thus this file has to be checked
out separately. And I don't want to get in the way of automating this by requiring
entries in web.config. 
</li>
          <li>
Package it as an assembly, so only the \bin folder needs to be copied to get up and
running. 
</li>
          <li>
The VirtualPathProvider requires (at the very least) anonymous access to the
repository. Passing security tokens is not implemented.</li>
        </ul>
        <p>
With those notes out of the way, thanks fly out to the ASP.NET team for providing
me with the sample of their virtual path provider in the first place. It has been
a tremendous help to get this thing off the ground. And maybe in turn this sample
will help others to get started:
</p>
        <p>
          <a href="http://chrison.net/content/binary/SvnVppDemo.zip">SvnVppDemo.zip (972.37
KB)</a>
        </p>
        <p>
          <strong>Installation note</strong>: the two DLLs in the system32 folder need to be
dropped in the respective folder of your system. Do not place them into \bin. Unless
you want to get into trouble, that is.
</p>
        <p>
What is left to say? Oh, the source code, of course! I thought you might be interested
in reading it online instead of having to download an almost 1MB-size file first.
Here it is (<em>App_Code\SubversionVirtualPathProvider.cs</em>):
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.IO;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Collections;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Globalization;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Configuration;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Text;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.Util;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.Hosting;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> System.Web.Caching;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> NSvn.Core;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">using</span> NSvn.Common;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">namespace</span> ICSharpCode.Web.Providers<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> SubversionVirtualPathProvider
: VirtualPathProvider<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">#region</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> HashCodeCombiner<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">sealed</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> HashCodeCombiner<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Start with a seed</span><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">long</span> _combinedHash <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 5381;<br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> AddLong(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">long</span> l)<br />
            {<br />
                _combinedHash <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ((_combinedHash
&lt;&lt; 5) <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> _combinedHash)
^ l;<br />
            }<br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> CombinedHashString<br />
            {<br />
                get<br />
                {<br />
                    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> _combinedHash.ToString(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"x"</span>,
CultureInfo.InvariantCulture);<br />
                }<br />
            }<br />
}<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">#endregion</span><br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">#region</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> SubversionVirtualFile<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> SubversionVirtualFile
: VirtualFile<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> fullPath;<br />
        DirectoryEntry entry;<br />
            <br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> SubversionVirtualFile(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualPath, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> fullPath,
DirectoryEntry entry)<br />
                : <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">base</span>(virtualPath)<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.fullPath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fullPath;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.entry <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> entry;<br />
        }<br />
            <br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> IsDirectory
{<br />
            get {<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> entry.NodeKind
== NodeKind.Directory;<br />
            }<br />
        }<br />
            <br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span> Stream
concat()<br />
        {<br />
            Client client <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Client();<br />
            MemoryStream
ms <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MemoryStream();<br />
            client.Cat(ms,
fullPath, Revision.Head);<br /><br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
.Cat closes the stream, so we have to copy it</span><br />
            MemoryStream
ms2 <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MemoryStream(ms.GetBuffer());<br />
            ms2.Position <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> ms2;<br />
        }<br />
}<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">#endregion</span><br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> AppInitialize()<br />
    {<br />
        SubversionVirtualPathProvider provider <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SubversionVirtualPathProvider();<br />
        HostingEnvironment.RegisterVirtualPathProvider(provider);<br />
    }<br />
        <br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> GetSvnFullpath(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualPath)<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span>.Parse(ConfigurationManager.AppSettings[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"svnvppStripVdir"</span>]))<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
this will break root Webs, StripVdir should be the default however</span><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> pos <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> virtualPath.IndexOf('<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/</span>',
1);<br />
            virtualPath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> virtualPath.Substring(pos,
virtualPath.Length <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">-</span> pos);<br />
        }<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> ConfigurationManager.AppSettings[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"svnvppRepositoryUrl"</span>]<br />
            <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> virtualPath;<br />
        }<br /><br />
    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> GetSvnFullpath(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualPath, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> fileName)<br />
    {<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> FixupSvnFullpath(GetSvnFullpath(virtualPath),
fileName);<br />
    }<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">    </font>//
Subversion is case sensitive, this we switch the filename here</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">    </font>string</span> FixupSvnFullpath(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> svnPath, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> fileName)<br />
    {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">        </font>int</span> pos <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> svnPath.LastIndexOf('<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/</span>');<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">        </font>string</span> parentDirectory <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> svnPath.Substring(0,
pos <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> 1);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">        </font>return</span> parentDirectory <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> fileName;<br />
    }<br />
        <br />
    DirectoryEntry GetEntry(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualPath)<br />
    {<br />
        Client svnClient <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Client();<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> fullPath <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> GetSvnFullpath(virtualPath);<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">int</span> pos <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fullPath.LastIndexOf('<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">/</span>');<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> parentDirectory <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fullPath.Substring(0,
pos);<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> entryName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fullPath.Substring(pos <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> 1);<br /><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">try</span><br />
        {<br />
            DirectoryEntry[]
entries <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> svnClient.List(parentDirectory,
Revision.Head, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">foreach</span> (DirectoryEntry
entry <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> entries) <br />
            {   <br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (0
== String.Compare(entry.Path, entryName, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>))<br />
                        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> entry;<br />
            }<br /><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br />
        } 
<br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">catch</span> (SvnClientException
ex) 
<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (ex.ErrorCode
== 160013) <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
parent directory not found</span><br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br /><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">throw</span>;<br />
        }<br />
    }<br />
        <br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> FileExists(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualPath)<br />
        {<br />
            DirectoryEntry
e <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> GetEntry(virtualPath);<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (e
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> e.NodeKind
== NodeKind.File;<br /><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> Previous.FileExists(virtualPath);<br />
        }<br />
        <br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> DirectoryExists(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualDir)<br />
        {<br />
            DirectoryEntry
e <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> GetEntry(virtualDir);<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (e
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> e.NodeKind
== NodeKind.Directory;<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> Previous.FileExists(virtualDir);<br />
        }<br />
        <br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Obtain the file. This will only be called if the hash that we return is</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
different than that the runtime holds on to as a cached indicator.</span><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span> VirtualFile
GetFile(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualPath)<br />
        {<br />
            DirectoryEntry
e <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> GetEntry(virtualPath);<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (e
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SubversionVirtualFile(virtualPath,
GetSvnFullpath(virtualPath, e.Path), e);<br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
Default to the previous implementation</span><br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> Previous.GetFile(virtualPath);<br />
        }<br />
        <br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
///////////////////////////////////////////////////////////////</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
Return a hash value indicating a key to test this file and dependencies have not been</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
modified</span><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> GetFileHash(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualPath,
IEnumerable virtualPathDependencies)<br />
        {<br />
            HashCodeCombiner
hashCodeCombiner <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> HashCodeCombiner();<br />
            <br />
            ArrayList
unrecognizedDependencies <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> ArrayList();<br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">foreach</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualDependency <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> virtualPathDependencies)<br />
            {<br />
                DirectoryEntry
e <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> GetEntry(virtualDependency);<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (e
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)
{<br />
                    hashCodeCombiner.AddLong(e.Size);<br />
                    hashCodeCombiner.AddLong(e.CreatedRevision);<br />
                } <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span> {<br />
                    unrecognizedDependencies.Add(unrecognizedDependencies);<br />
                }<br />
            }<br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> result <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> hashCodeCombiner.CombinedHashString;<br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (unrecognizedDependencies.Count
&gt; 0)<br />
            {<br />
                result
+= Previous.GetFileHash(virtualPath, unrecognizedDependencies);<br />
            }<br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> result;<br />
        }<br />
        <br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
///////////////////////////////////////////////////////////////</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
The cache dependency is a specialized object that means that the runtime</span><br />
        <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">///
can perform file monitoring and change notifications directly</span><br />
        <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span> CacheDependency
GetCacheDependency(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> virtualPath,
IEnumerable virtualPathDependencies, DateTime utcStart)<br />
        {<br />
            <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
This VPP does not create CacheDependencies</span><br />
            DirectoryEntry
e <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> GetEntry(virtualPath);<br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (e
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br />
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> Previous.GetCacheDependency(virtualPath,
virtualPathDependencies, utcStart);<br />
        }<br />
    }<br />
}<br /></span>
        </p>
        <p>
 
</p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=30b39cc2-8175-4b20-938d-60148fcea6de" />
      </body>
      <title>Writing a Subversion-backed VirtualPathProvider for ASP.NET 2.0</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,30b39cc2-8175-4b20-938d-60148fcea6de.aspx</guid>
      <link>http://chrison.net/WritingASubversionbackedVirtualPathProviderForASPNET20.aspx</link>
      <pubDate>Wed, 27 Jul 2005 06:18:56 GMT</pubDate>
      <description>&lt;p&gt;
This post is again motivated by last week's Community Bootcamp on ASP.NET 2.0, the &lt;a href="http://www.dotnetgerman.com/community/cbc05/"&gt;CBC05&lt;/a&gt;.
I presented "Under the Covers - Exploring Internals, Page Lifecycle and the Compilation
Mode" from TechEd, using the samples that Simon Calvert provided me with (special
thanks fly out to Simon, Ben Miller and Rich Ersek @MS for providing us with material
- I know I can be a royal pain in the posterior... sometimes at least). 
&lt;/p&gt;
&lt;p&gt;
The talk included a demo of a database-backed virtual path provider (files don't come
from the file system but a database, dynamically). Somehow we started talking about
how cool it would&amp;nbsp;be if you could test your Web sites without checking them out
from source control in the first place - by simply writing a virtual path provider
that goes to the repository on demand. I wrote that idea down.
&lt;/p&gt;
&lt;p&gt;
Actually, I didn't think I'd get around to doing that. But yesterday I decided to
pester one of my devs on the &lt;a href="http://www.icsharpcode.net/OpenSource/SD/Default.aspx"&gt;#develop&lt;/a&gt; project,
namely &lt;a href="http://wiki.sharpdevelop.net/default.aspx/SharpDevelop.DanielGrunwald"&gt;Daniel
Grunwald&lt;/a&gt;. He has implemented the &lt;a href="http://subversion.tigris.org"&gt;Subversion&lt;/a&gt; addin
for our 2.0 version, so he had experience with NSvn, the managed API for talking to
Subversion. I sent a stripped down version of the vpath provider to him, and asked
him to replace database code with NSvn code where appropriate.
&lt;/p&gt;
&lt;p&gt;
It didn't take long, and I had a command-line verified version back, and all I had
to do was make sure that it works with ASP.NET 2.0. There were a few problems I ran
into (like Subversion is case-sensitive and I didn't want that for the Web scenario).
Some of the issues arose simply because client and Web developers have different backgrounds.
Talk about path separators. Or directories where you have to drop assemblies.
&lt;/p&gt;
&lt;p&gt;
Now, let's stop talking, let's take a look at the provider in action:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/SvnVPathProvider.wmv"&gt;SvnVPathProvider.wmv
(3.76 MB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Want to get your hands on that DemoSiteSvn directory with the current rendition of
the SubversionVirtualPathProvider? No problem, just a couple of notes up front on
what you should be aware of:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Only file names are currently treated specially for casing. Ie directories still do
react in a case sensitive way. 
&lt;li&gt;
The file name cracking code needs to be reviewed. Currently, this is a quick hack. 
&lt;li&gt;
appSettings need to be placed in a separate .config file. Reason is that web.config
cannot be obtained via a VirtualPathProvider, and thus this file has to be checked
out separately. And I don't want to get in the way of automating this by requiring
entries in web.config. 
&lt;li&gt;
Package it as an assembly, so only the \bin folder needs to be copied to get up and
running. 
&lt;li&gt;
The VirtualPathProvider requires (at the very least)&amp;nbsp;anonymous access to the
repository. Passing security tokens is not implemented.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
With those notes out of the way, thanks fly out to the ASP.NET team for providing
me with the sample of their virtual path provider in the first place. It has been
a tremendous help to get this thing off the ground. And maybe in turn this sample
will help others to get started:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/SvnVppDemo.zip"&gt;SvnVppDemo.zip (972.37
KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Installation note&lt;/strong&gt;: the two DLLs in the system32 folder need to be
dropped in the respective folder of your system. Do not place them into \bin. Unless
you want to get into trouble, that is.
&lt;/p&gt;
&lt;p&gt;
What is left to say? Oh, the source code, of course! I thought you might be interested
in reading it online instead of having to download an almost 1MB-size file first.
Here it is (&lt;em&gt;App_Code\SubversionVirtualPathProvider.cs&lt;/em&gt;):
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.IO;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Collections;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Globalization;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Configuration;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Text;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.Util;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.Hosting;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; System.Web.Caching;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; NSvn.Core;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;using&lt;/span&gt; NSvn.Common;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;namespace&lt;/span&gt; ICSharpCode.Web.Providers&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; SubversionVirtualPathProvider
: VirtualPathProvider&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;#region&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; HashCodeCombiner&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;sealed&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; HashCodeCombiner&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Start with a seed&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;long&lt;/span&gt; _combinedHash &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 5381;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; AddLong(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;long&lt;/span&gt; l)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_combinedHash &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ((_combinedHash
&amp;lt;&amp;lt; 5) &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; _combinedHash)
^ l;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; CombinedHashString&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; _combinedHash.ToString(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"x"&lt;/span&gt;,
CultureInfo.InvariantCulture);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;#endregion&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;#region&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; SubversionVirtualFile&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; SubversionVirtualFile
: VirtualFile&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; fullPath;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DirectoryEntry entry;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; SubversionVirtualFile(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualPath, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; fullPath,
DirectoryEntry entry)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;base&lt;/span&gt;(virtualPath)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.fullPath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fullPath;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt;.entry &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; entry;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; IsDirectory
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; entry.NodeKind
== NodeKind.Directory;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; Stream
concat()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Client client &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Client();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MemoryStream
ms &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MemoryStream();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client.Cat(ms,
fullPath, Revision.Head);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
.Cat closes the stream, so we have to copy it&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MemoryStream
ms2 &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MemoryStream(ms.GetBuffer());&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ms2.Position &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; ms2;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;#endregion&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; AppInitialize()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SubversionVirtualPathProvider provider &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SubversionVirtualPathProvider();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HostingEnvironment.RegisterVirtualPathProvider(provider);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; GetSvnFullpath(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualPath)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt;.Parse(ConfigurationManager.AppSettings[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"svnvppStripVdir"&lt;/span&gt;]))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
this will break root Webs, StripVdir should be the default however&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; pos &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; virtualPath.IndexOf('&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&lt;/span&gt;',
1);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;virtualPath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; virtualPath.Substring(pos,
virtualPath.Length &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;-&lt;/span&gt; pos);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; ConfigurationManager.AppSettings[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"svnvppRepositoryUrl"&lt;/span&gt;]&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; virtualPath;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; GetSvnFullpath(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualPath, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; fileName)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; FixupSvnFullpath(GetSvnFullpath(virtualPath),
fileName);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;//
Subversion is case sensitive, this we switch the filename here&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;string&lt;/span&gt; FixupSvnFullpath(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; svnPath, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; fileName)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;int&lt;/span&gt; pos &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; svnPath.LastIndexOf('&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&lt;/span&gt;');&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;string&lt;/span&gt; parentDirectory &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; svnPath.Substring(0,
pos &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; 1);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;return&lt;/span&gt; parentDirectory &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; fileName;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DirectoryEntry GetEntry(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualPath)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Client svnClient &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; Client();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; fullPath &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; GetSvnFullpath(virtualPath);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;int&lt;/span&gt; pos &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fullPath.LastIndexOf('&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&lt;/span&gt;');&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; parentDirectory &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fullPath.Substring(0,
pos);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; entryName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fullPath.Substring(pos &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; 1);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;try&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DirectoryEntry[]
entries &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; svnClient.List(parentDirectory,
Revision.Head, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;foreach&lt;/span&gt; (DirectoryEntry
entry &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; entries)&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (0
== String.Compare(entry.Path, entryName, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; entry;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;catch&lt;/span&gt; (SvnClientException
ex) 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (ex.ErrorCode
== 160013) &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
parent directory not found&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;throw&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; FileExists(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualPath)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DirectoryEntry
e &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; GetEntry(virtualPath);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (e
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; e.NodeKind
== NodeKind.File;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; Previous.FileExists(virtualPath);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; DirectoryExists(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualDir)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DirectoryEntry
e &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; GetEntry(virtualDir);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (e
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; e.NodeKind
== NodeKind.Directory;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; Previous.FileExists(virtualDir);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Obtain the file. This will only be called if the hash that we return is&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
different than that the runtime holds on to as a cached indicator.&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; VirtualFile
GetFile(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualPath)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DirectoryEntry
e &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; GetEntry(virtualPath);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (e
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SubversionVirtualFile(virtualPath,
GetSvnFullpath(virtualPath, e.Path), e);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
Default to the previous implementation&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; Previous.GetFile(virtualPath);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
///////////////////////////////////////////////////////////////&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
Return a hash value indicating a key to test this file and dependencies have not been&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
modified&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; GetFileHash(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualPath,
IEnumerable virtualPathDependencies)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HashCodeCombiner
hashCodeCombiner &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; HashCodeCombiner();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ArrayList
unrecognizedDependencies &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; ArrayList();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;foreach&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualDependency &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; virtualPathDependencies)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DirectoryEntry
e &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; GetEntry(virtualDependency);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (e
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hashCodeCombiner.AddLong(e.Size);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hashCodeCombiner.AddLong(e.CreatedRevision);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unrecognizedDependencies.Add(unrecognizedDependencies);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; result &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; hashCodeCombiner.CombinedHashString;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (unrecognizedDependencies.Count
&amp;gt; 0)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result
+= Previous.GetFileHash(virtualPath, unrecognizedDependencies);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; result;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
///////////////////////////////////////////////////////////////&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
The cache dependency is a specialized object that means that the runtime&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;///
can perform file monitoring and change notifications directly&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; CacheDependency
GetCacheDependency(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; virtualPath,
IEnumerable virtualPathDependencies, DateTime utcStart)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
This VPP does not create CacheDependencies&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DirectoryEntry
e &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; GetEntry(virtualPath);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (e
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; Previous.GetCacheDependency(virtualPath,
virtualPathDependencies, utcStart);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=30b39cc2-8175-4b20-938d-60148fcea6de" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,30b39cc2-8175-4b20-938d-60148fcea6de.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Community</category>
      <category>Subversion</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=4b1ffee3-1342-4317-8fd3-d4183cf3f7b1</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,4b1ffee3-1342-4317-8fd3-d4183cf3f7b1.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,4b1ffee3-1342-4317-8fd3-d4183cf3f7b1.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=4b1ffee3-1342-4317-8fd3-d4183cf3f7b1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Script Callbacks were also part of my "Advanced ASP.NET 2.0" day at the <a href="http://www.dotnetgerman.com/community/cbc05/">Community
Bootcamp 2005</a> in Bad Ischl. Aside from showing the usual callback sample, I decided
that something more useful was in order. That is why I went a tad further by showing
off the controls introduced in the <a href="http://www.gotdotnet.com/workspaces/workspace.aspx?id=cb2543cb-12ec-4ea1-883f-757ff2de19e8">RefreshPanel
GotDotNet workspace</a>. I came across those a while back when reading articles on <a href="http://weblogs.asp.net/bleroy">Bertrand
Le Roy's blog</a>:
</p>
        <ul>
          <li>
            <a href="http://weblogs.asp.net/bleroy/archive/2005/04/08/397761.aspx">Fun with callbacks
Part 1: What's in the ASP.NET box? </a>
          </li>
          <li>
            <a href="http://weblogs.asp.net/bleroy/archive/2005/04/15/400792.aspx">Fun with callbacks,
Part 2: The RefreshPanel</a>
          </li>
          <li>
            <a href="http://weblogs.asp.net/bleroy/archive/2005/05/19/407539.aspx">Fun with callbacks
Part 3: Strongly-typed callbacks</a>
          </li>
          <li>
            <a href="http://weblogs.asp.net/bleroy/archive/2005/06/27/415936.aspx">Fun with callbacks
Part 4: What about postback events?</a>
          </li>
        </ul>
        <p>
Of course we did labs on CallbackProxy and RefreshPanel, the latter one is described
in this blog entry (again, a streamlined version of the lab done by Alexander Schoeppl).
</p>
        <p>
Let's start with the result we wanted to achieve:
</p>
        <p>
          <img src="http://chrison.net/content/binary/cbc05callbacks.png" border="0" />
        </p>
        <p>
The render date only acts as a "proof" that no Postback happened, the dropdown control
lists all customers in Northwind and is also populated up front. The GridView control,
however, is filled using out of band calls. Instead of hacking your own ugly JavaScript,
we did that using the RefreshPanel control.
</p>
        <p>
          <strong>Step 1: Copy RefreshPanel.dll</strong>
        </p>
        <p>
First, copy RefreshPanel.dll to the \bin directory of your site. You can get it <a href="http://www.gotdotnet.com/workspaces/workspace.aspx?id=cb2543cb-12ec-4ea1-883f-757ff2de19e8">here</a>.
</p>
        <p>
          <strong>Step 2: Set up a connection string in web.config</strong>
        </p>
        <p>
We will use that later both in markup and code beside file:
</p>
        <pre>&lt;connectionStrings&gt;<br />
 &lt;add name="NorthwindConnectionString" 
<br />
connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/&gt;<br />
&lt;/connectionStrings&gt;</pre>
        <p>
          <strong>Step 3: ShowCustomerOrders.aspx</strong>
        </p>
        <p>
Basically, "organized" in three sections (separated by a blank line):
</p>
        <pre>&lt;%@ Page Language="C#" AutoEventWireup="true" 
<br />
CodeFile="ShowCustomerOrders.aspx.cs" Inherits="Show_Customer_Orders" 
<br />
Title="Callback Demo" %&gt;<br />
&lt;%@ Register TagPrefix="rp" Namespace="MyControls.RefreshPanel" 
<br />
Assembly="RefreshPanel" %&gt;</pre>
        <pre>&lt;html xmlns="<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"
&gt;<br />
&lt;head runat="server"&gt;<br />
    &lt;title&gt;Untitled Page&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
    &lt;form id="form1" runat="server"&gt;<br />
    &lt;div&gt;<br />
        Render Date: &lt;asp:Literal ID="Literal1"
runat="server"&gt;&lt;/asp:Literal&gt;<br />
        &lt;br /&gt;<br />
        
<br />
        &lt;asp:DropDownList ID="DropDownList1"
runat="server" 
<br />
DataSourceID="SqlDataSource1" DataTextField="CustomerID" 
<br />
DataValueField="CustomerID"&gt;<br />
        &lt;/asp:DropDownList&gt;<br />
&lt;asp:SqlDataSource ID="SqlDataSource1" runat="server" 
<br />
ConnectionString="&lt;%$ ConnectionStrings:NorthwindConnectionString %&gt;"<br />
            SelectCommand="SELECT
[CustomerID] FROM [Customers]"&gt;<br />
&lt;/asp:SqlDataSource&gt;<br />
        &lt;rp:RefreshButton ID="MyButton" RefreshPanelID="RFPanel1" 
<br />
            runat="server" 
<br />
            ClientRefreshArgument="this.form.DropDownList1.options[this.form.DropDownList1.selectedIndex].value" 
<br />
            Text="Show Orders"/&gt;<br />
        &lt;br /&gt;<br />
        
<br />
        &lt;rp:RefreshPanel runat="server" ID="RFPanel1"
OnRefreshing="FillData"&gt;<br />
            &lt;asp:GridView
ID="GridView1" runat="server"&gt;<br />
            &lt;/asp:GridView&gt;<br />
        &lt;/rp:RefreshPanel&gt;<br />
    &lt;/div&gt;<br />
    &lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</pre>
        <p>
Register imports the <em>RefreshPanel</em> control suite for us, the Label and
DropDown are also very straightforward. The <em>RefreshPanel</em> control itself contains
a single GridView control, and it is linked to the server-side method <em>FillData</em> which
we will examine in the next step. The <em>RefreshButton</em> is responsible for activating
the out of band call back to the server - that's also where we get the value from
the dropdown control, and pass it as an event argument to <em>FillData</em>. 
</p>
        <p>
Note that the control names are hardcoded, in the real world we'd build that string
dynamically, because otherwise we'd get into trouble, eg with master pages.
</p>
        <p>
          <strong>Step 4: ShowCustomerOrders.aspx.cs</strong>
        </p>
        <p>
          <em>Page_Load</em> is trivial, we are only interested in <em>FillData</em>:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> FillData(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
RefreshingEventArgs e)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> connectionString <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ConfigurationManager.ConnectionStrings[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"NorthwindConnectionString"</span>].ToString();<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> sqlCmd <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Select
* from Orders where customerID = @CustomerID"</span>;<br /><br />
SqlConnection conn <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SqlConnection(connectionString);<br /><br />
SqlCommand cmd <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SqlCommand(sqlCmd,
conn);<br />
cmd.Parameters.AddWithValue(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"@CustomerID"</span>,
(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>)e.EventArgument);<br /><br />
conn.Open();<br />
SqlDataReader reader <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> cmd.ExecuteReader();<br /><br />
GridView1.DataSource <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> reader;<br />
GridView1.DataBind();<br />
reader.Close();<br />
conn.Close();<br />
}</span>
        </p>
        <p>
No magic in our code, but: <em>RefreshPanel</em> takes care of giving us a GridView
control to work with, and shipping the resulting HTML to the client - and inserting
it into the page. Very, very neat indeed.
</p>
        <p>
          <a href="http://chrison.net/content/binary/CallbackDemo.zip">CallbackDemo.zip (43.51
KB)</a>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=4b1ffee3-1342-4317-8fd3-d4183cf3f7b1" />
      </body>
      <title>Callbacks in ASP.NET 2.0</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,4b1ffee3-1342-4317-8fd3-d4183cf3f7b1.aspx</guid>
      <link>http://chrison.net/CallbacksInASPNET20.aspx</link>
      <pubDate>Tue, 26 Jul 2005 13:24:14 GMT</pubDate>
      <description>&lt;p&gt;
Script Callbacks were also part of my "Advanced ASP.NET 2.0" day at the &lt;a href="http://www.dotnetgerman.com/community/cbc05/"&gt;Community
Bootcamp 2005&lt;/a&gt; in Bad Ischl. Aside from showing the usual callback sample, I decided
that something more useful was in order. That is why I went a tad further by showing
off the controls introduced in the &lt;a href="http://www.gotdotnet.com/workspaces/workspace.aspx?id=cb2543cb-12ec-4ea1-883f-757ff2de19e8"&gt;RefreshPanel
GotDotNet workspace&lt;/a&gt;. I came across those a while back when reading articles on &lt;a href="http://weblogs.asp.net/bleroy"&gt;Bertrand
Le Roy's blog&lt;/a&gt;:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://weblogs.asp.net/bleroy/archive/2005/04/08/397761.aspx"&gt;Fun with callbacks
Part 1: What's in the ASP.NET box? &lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://weblogs.asp.net/bleroy/archive/2005/04/15/400792.aspx"&gt;Fun with callbacks,
Part 2: The RefreshPanel&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://weblogs.asp.net/bleroy/archive/2005/05/19/407539.aspx"&gt;Fun with callbacks
Part 3: Strongly-typed callbacks&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://weblogs.asp.net/bleroy/archive/2005/06/27/415936.aspx"&gt;Fun with callbacks
Part 4: What about postback events?&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Of course we did labs on CallbackProxy and RefreshPanel, the latter one is described
in this blog entry (again, a streamlined version of the lab done by Alexander Schoeppl).
&lt;/p&gt;
&lt;p&gt;
Let's start with the result we wanted to achieve:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://chrison.net/content/binary/cbc05callbacks.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
The render date only acts as a "proof" that no Postback happened, the dropdown control
lists all customers in Northwind and is also populated up front. The GridView control,
however, is filled using out of band calls. Instead of hacking your own ugly JavaScript,
we did that using the RefreshPanel control.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Step 1: Copy RefreshPanel.dll&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
First, copy RefreshPanel.dll to the \bin directory of your site. You can get it &lt;a href="http://www.gotdotnet.com/workspaces/workspace.aspx?id=cb2543cb-12ec-4ea1-883f-757ff2de19e8"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Step 2: Set up a connection string in web.config&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
We will use that later both in markup and code beside file:
&lt;/p&gt;
&lt;pre&gt;&amp;lt;connectionStrings&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;lt;add name="NorthwindConnectionString" 
&lt;br&gt;
connectionString="Data Source=cbc05vpc\cbc05;Initial Catalog=Northwind;User=sa;Password=P@ssw0rd"/&amp;gt;&lt;br&gt;
&amp;lt;/connectionStrings&amp;gt;&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Step 3: ShowCustomerOrders.aspx&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Basically, "organized" in three sections (separated by a blank line):
&lt;/p&gt;
&lt;pre&gt;&amp;lt;%@ Page Language="C#" AutoEventWireup="true" 
&lt;br&gt;
CodeFile="ShowCustomerOrders.aspx.cs" Inherits="Show_Customer_Orders" 
&lt;br&gt;
Title="Callback Demo" %&amp;gt;&lt;br&gt;
&amp;lt;%@ Register TagPrefix="rp" Namespace="MyControls.RefreshPanel" 
&lt;br&gt;
Assembly="RefreshPanel" %&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;html xmlns="&lt;a href="http://www.w3.org/1999/xhtml"&gt;http://www.w3.org/1999/xhtml&lt;/a&gt;"
&amp;gt;&lt;br&gt;
&amp;lt;head runat="server"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;Untitled Page&amp;lt;/title&amp;gt;&lt;br&gt;
&amp;lt;/head&amp;gt;&lt;br&gt;
&amp;lt;body&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;form id="form1" runat="server"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Render Date: &amp;lt;asp:Literal ID="Literal1"
runat="server"&amp;gt;&amp;lt;/asp:Literal&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;br /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:DropDownList ID="DropDownList1"
runat="server" 
&lt;br&gt;
DataSourceID="SqlDataSource1" DataTextField="CustomerID" 
&lt;br&gt;
DataValueField="CustomerID"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:DropDownList&amp;gt;&lt;br&gt;
&amp;lt;asp:SqlDataSource ID="SqlDataSource1" runat="server" 
&lt;br&gt;
ConnectionString="&amp;lt;%$ ConnectionStrings:NorthwindConnectionString %&amp;gt;"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SelectCommand="SELECT
[CustomerID] FROM [Customers]"&amp;gt;&lt;br&gt;
&amp;lt;/asp:SqlDataSource&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;rp:RefreshButton ID="MyButton" RefreshPanelID="RFPanel1" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; runat="server" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ClientRefreshArgument="this.form.DropDownList1.options[this.form.DropDownList1.selectedIndex].value" 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Text="Show Orders"/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;br /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;rp:RefreshPanel runat="server" ID="RFPanel1"
OnRefreshing="FillData"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:GridView
ID="GridView1" runat="server"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/asp:GridView&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/rp:RefreshPanel&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/form&amp;gt;&lt;br&gt;
&amp;lt;/body&amp;gt;&lt;br&gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;
&lt;p&gt;
Register imports the &lt;em&gt;RefreshPanel&lt;/em&gt; control suite&amp;nbsp;for us, the Label and
DropDown are also very straightforward. The &lt;em&gt;RefreshPanel&lt;/em&gt; control itself contains
a single GridView control, and it is linked to the server-side method &lt;em&gt;FillData&lt;/em&gt; which
we will examine in the next step. The &lt;em&gt;RefreshButton&lt;/em&gt; is responsible for activating
the out of band call back to the server - that's also where we get the value from
the dropdown control, and pass it as an event argument to &lt;em&gt;FillData&lt;/em&gt;. 
&lt;/p&gt;
&lt;p&gt;
Note that the control names are hardcoded, in the real world we'd build that string
dynamically, because otherwise we'd get into trouble, eg with master pages.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Step 4: ShowCustomerOrders.aspx.cs&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Page_Load&lt;/em&gt; is trivial, we are only interested in &lt;em&gt;FillData&lt;/em&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; FillData(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
RefreshingEventArgs e)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; connectionString &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ConfigurationManager.ConnectionStrings[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"NorthwindConnectionString"&lt;/span&gt;].ToString();&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; sqlCmd &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Select
* from Orders where customerID = @CustomerID"&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
SqlConnection conn &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SqlConnection(connectionString);&lt;br&gt;
&lt;br&gt;
SqlCommand cmd &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SqlCommand(sqlCmd,
conn);&lt;br&gt;
cmd.Parameters.AddWithValue(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@CustomerID"&lt;/span&gt;,
(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;)e.EventArgument);&lt;br&gt;
&lt;br&gt;
conn.Open();&lt;br&gt;
SqlDataReader reader &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; cmd.ExecuteReader();&lt;br&gt;
&lt;br&gt;
GridView1.DataSource &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; reader;&lt;br&gt;
GridView1.DataBind();&lt;br&gt;
reader.Close();&lt;br&gt;
conn.Close();&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
No magic in our code, but: &lt;em&gt;RefreshPanel&lt;/em&gt; takes care of giving us a GridView
control to work with, and shipping the resulting HTML to the client - and inserting
it into the page. Very, very neat indeed.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/CallbackDemo.zip"&gt;CallbackDemo.zip (43.51
KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=4b1ffee3-1342-4317-8fd3-d4183cf3f7b1" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,4b1ffee3-1342-4317-8fd3-d4183cf3f7b1.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>this</category>
      <category>Training and Conferences</category>
    </item>
    <item>
      <trackback:ping>http://chrison.net/Trackback.aspx?guid=c776faf3-471f-43f7-b19e-cdc0dcadff99</trackback:ping>
      <pingback:server>http://chrison.net/pingback.aspx</pingback:server>
      <pingback:target>http://chrison.net/PermaLink,guid,c776faf3-471f-43f7-b19e-cdc0dcadff99.aspx</pingback:target>
      <dc:creator>Christoph Wille</dc:creator>
      <wfw:comment>http://chrison.net/CommentView,guid,c776faf3-471f-43f7-b19e-cdc0dcadff99.aspx</wfw:comment>
      <wfw:commentRss>http://chrison.net/SyndicationService.asmx/GetEntryCommentsRss?guid=c776faf3-471f-43f7-b19e-cdc0dcadff99</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
On Friday, it was my turn as speaker at the <a href="http://www.dotnetgerman.com/community/cbc05/">Community
Bootcamp 2005</a> aka <a href="http://www.dotnetgerman.com/community/cbc05/">CBC05</a>.
One of the topics at hand was "The Provider Model", with a focus on Membership providers.
Those are the ones most likely being extended / written from scratch, and we did an
exercise in that very area: Extend the SqlMembershipProvider to audit successful and
failed logins similar to *nix. The solution I present today is a streamlined solution
programmed by Alexander Schoeppl, one of the attendees.
</p>
        <p>
          <strong>Step 1: Create the table</strong>
        </p>
        <pre>CREATE TABLE [dbo].[myLoginAuditing](<br />
 [username] [varchar](255) NOT NULL,<br />
 [numberofSuccessfulLogins] [int] NOT NULL,<br />
 [numberofFailedLogins] [int] NOT NULL,<br />
 [lastFailedLogin] [datetime] NOT NULL,<br />
 [lastFailedLoginIP] [varchar](15) NOT NULL)</pre>
        <p>
          <strong>Step 2: Create the stored procedure</strong>
        </p>
        <pre>create procedure myLogUserVisit(<br />
  @username as Varchar(255), 
<br />
  @success as int,<br />
  @lastfailedLoginIP as varchar(15))<br />
as<br />
   IF ( EXISTS ( SELECT username<br />
                 
FROM   dbo.myLoginAuditing<br />
                 
WHERE  username = @username ) )<br />
    BEGIN<br />
    if (@success = 1)<br />
    Begin<br />
      update myLoginAuditing set 
<br />
numberofSuccessfulLogins = numberofSuccessfulLogins + 1 
<br />
        where username = @username<br />
    End<br />
    else<br />
    begin<br />
      update myLoginAuditing set 
<br />
numberofFailedLogins = numberofFailedLogins + 1,<br />
                   
lastFailedLogin = GetDate(),<br />
                   
lastfailedLoginIP = @lastFailedLoginIP<br />
        where username = @username<br />
    end<br />
  END<br />
  ELSE<br />
  BEGIN<br />
    if (@success = 1)<br />
    Begin<br />
      insert into myLoginAuditing (username, numberofSuccessfulLogins, 
<br />
numberoffailedlogins, lastfailedlogin, lastfailedloginip) 
<br />
values (@username, 1, 0, '01.01.1900', '')<br />
    End<br />
    else<br />
    begin<br />
      insert into myLoginAuditing (username, numberofSuccessfulLogins, 
<br />
numberoffailedlogins, lastfailedlogin, lastfailedloginip) 
<br />
values (@username, 0, 1, GetDate(), @lastfailedLoginIP)<br />
    end    
<br />
  END<br /></pre>
        <p>
Alexander did a smart thing - he looked at the various aspnet* sp's.
</p>
        <p>
          <strong>Step 3: Write the Membership provider</strong>
        </p>
        <p>
The class skeleton looks like this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> MyMembershipProvider
: SqlMembershipProvider 
<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> ValidateUser(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> username, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> password)<br />
{<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Initialize(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> name,
System.Collections.Specialized.NameValueCollection config)<br />
{<br />
}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span> MembershipUser
GetUser(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> username, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> userIsOnline)<br />
{<br />
}<br />
}<br /></span>
        </p>
        <p>
Initialize is the easy but essential part - we need the connection string name for
later:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> connectionStringName;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Initialize(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> name,
System.Collections.Specialized.NameValueCollection config)<br />
{<br />
connectionStringName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> config[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"connectionStringName"</span>];<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">base</span>.Initialize(name,
config);<br />
}</span>
        </p>
        <p>
Now we can validate the user - well, the base class does that. We only do the auditing
part:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> ValidateUser(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> username, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> password)<br />
{<br />
HttpContext.Current.Trace.Write(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"ValidateUser:entry"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> bSuccess <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">base</span>.ValidateUser(username,
password);<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> connectionString <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;<br /><br />
SqlConnection conn <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SqlConnection(connectionString);<br />
SqlCommand cmd <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SqlCommand(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"exec
myLogUserVisit @username, @success, @IP"</span>, conn);<br /><br />
cmd.Parameters.AddWithValue(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"@username"</span>,
username);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (bSuccess) 
<br />
  cmd.Parameters.AddWithValue(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"@success"</span>,
1);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><br />
  cmd.Parameters.AddWithValue(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"@success"</span>,
0);<br /><br />
cmd.Parameters.AddWithValue(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"@IP"</span>,
HttpContext.Current.Request.UserHostAddress);<br /><br />
conn.Open();<br />
cmd.ExecuteNonQuery();<br />
conn.Close();<br /><br />
HttpContext.Current.Trace.Write(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"ValidateUser:exit"</span>);<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> bSuccess;<br />
}</span>
        </p>
        <p>
          <strong>Step 4: Set it up - web.config</strong>
        </p>
        <pre>  &lt;appSettings/&gt;<br />
  &lt;connectionStrings&gt;<br />
    &lt;add name="MyNWind" connectionString="Data Source=cbc05vpc\cbc05;Initial
Catalog=Northwind;User=sa;Password=P@ssw0rd"/&gt;<br />
  &lt;/connectionStrings&gt;<br />
  
<br />
  &lt;system.web&gt;<br />
    &lt;membership defaultProvider="SuperDuperMSProv"&gt;<br />
      &lt;providers&gt;<br />
        &lt;clear/&gt;<br />
        &lt;add name="SuperDuperMSProv" connectionStringName="MyNWind"
type="MyMembershipProvider"/&gt;<br />
      &lt;/providers&gt;<br />
    &lt;/membership&gt;</pre>
        <p>
          <strong>Step 5: View the auditing information - default.aspx.cs</strong>
        </p>
        <p>
The final "UI" looks like this:
</p>
        <img src="http://chrison.net/content/binary/cbc05membershipprovider.png" border="0" />
        <p>
The source code is rather simple:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">protected</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Page_Load(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
EventArgs e)<br />
{<br />
MyMembershipUser currentUser <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> (MyMembershipUser)Membership.GetUser();<br /><br />
Label1.Text <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> currentUser.FullName;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> lcConnection <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> ConfigurationManager.ConnectionStrings[<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"MyNWind"</span>].ConnectionString;<br /><br />
SqlConnection conn <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SqlConnection(lcConnection);<br /><br />
SqlCommand cmd <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SqlCommand(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"select
* from myLoginAuditing where username=@username"</span>, conn);<br />
cmd.Parameters.AddWithValue(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"@Username"</span>,
currentUser.UserName);<br /><br />
conn.Open();<br /><br />
SqlDataReader reader <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> cmd.ExecuteReader();<br /><br />
GridView1.DataSource <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> reader;<br />
GridView1.DataBind();<br /><br />
reader.Close();<br />
conn.Close();<br />
}</span>
        </p>
        <p>
Done. By the way, did you notice something? Right! Alexander never fell into the trap
of SQL Injection.
</p>
        <p>
          <a href="http://chrison.net/content/binary/ExtendingMembershipProviderDemo.zip">ExtendingMembershipProviderDemo.zip
(5.64 KB)</a>
        </p>
        <img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=c776faf3-471f-43f7-b19e-cdc0dcadff99" />
      </body>
      <title>Adding auditing capabilities to SqlMembershipProvider</title>
      <guid isPermaLink="false">http://chrison.net/PermaLink,guid,c776faf3-471f-43f7-b19e-cdc0dcadff99.aspx</guid>
      <link>http://chrison.net/AddingAuditingCapabilitiesToSqlMembershipProvider.aspx</link>
      <pubDate>Mon, 25 Jul 2005 17:46:16 GMT</pubDate>
      <description>&lt;p&gt;
On Friday, it was my turn as speaker at the &lt;a href="http://www.dotnetgerman.com/community/cbc05/"&gt;Community
Bootcamp 2005&lt;/a&gt; aka &lt;a href="http://www.dotnetgerman.com/community/cbc05/"&gt;CBC05&lt;/a&gt;.
One of the topics at hand was "The Provider Model", with a focus on Membership providers.
Those are the ones most likely being extended / written from scratch, and we did an
exercise in that very area: Extend the SqlMembershipProvider to audit successful and
failed logins similar to *nix. The solution I present today is a streamlined solution
programmed by Alexander Schoeppl, one of the attendees.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Step 1: Create the table&lt;/strong&gt;
&lt;/p&gt;
&lt;pre&gt;CREATE TABLE [dbo].[myLoginAuditing](&lt;br&gt;
&amp;nbsp;[username] [varchar](255) NOT NULL,&lt;br&gt;
&amp;nbsp;[numberofSuccessfulLogins] [int] NOT NULL,&lt;br&gt;
&amp;nbsp;[numberofFailedLogins] [int] NOT NULL,&lt;br&gt;
&amp;nbsp;[lastFailedLogin] [datetime] NOT NULL,&lt;br&gt;
&amp;nbsp;[lastFailedLoginIP] [varchar](15) NOT NULL)&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Step 2: Create the stored procedure&lt;/strong&gt;
&lt;/p&gt;
&lt;pre&gt;create procedure myLogUserVisit(&lt;br&gt;
&amp;nbsp; @username as Varchar(255), 
&lt;br&gt;
&amp;nbsp; @success as int,&lt;br&gt;
&amp;nbsp; @lastfailedLoginIP as varchar(15))&lt;br&gt;
as&lt;br&gt;
&amp;nbsp;&amp;nbsp; IF ( EXISTS ( SELECT username&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
FROM&amp;nbsp;&amp;nbsp; dbo.myLoginAuditing&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WHERE&amp;nbsp; username = @username ) )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; BEGIN&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (@success = 1)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Begin&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; update myLoginAuditing set 
&lt;br&gt;
numberofSuccessfulLogins = numberofSuccessfulLogins + 1 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where username = @username&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; End&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; update myLoginAuditing set 
&lt;br&gt;
numberofFailedLogins = numberofFailedLogins + 1,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
lastFailedLogin = GetDate(),&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
lastfailedLoginIP = @lastFailedLoginIP&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where username = @username&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br&gt;
&amp;nbsp; END&lt;br&gt;
&amp;nbsp; ELSE&lt;br&gt;
&amp;nbsp; BEGIN&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (@success = 1)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Begin&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; insert into myLoginAuditing (username, numberofSuccessfulLogins, 
&lt;br&gt;
numberoffailedlogins, lastfailedlogin, lastfailedloginip) 
&lt;br&gt;
values (@username, 1, 0, '01.01.1900', '')&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; End&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; insert into myLoginAuditing (username, numberofSuccessfulLogins, 
&lt;br&gt;
numberoffailedlogins, lastfailedlogin, lastfailedloginip) 
&lt;br&gt;
values (@username, 0, 1, GetDate(), @lastfailedLoginIP)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp; END&lt;br&gt;
&lt;/pre&gt;
&lt;p&gt;
Alexander did a smart thing - he looked at the various aspnet* sp's.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Step 3: Write the Membership provider&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The class skeleton looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; MyMembershipProvider
: SqlMembershipProvider 
&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; ValidateUser(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; username, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; password)&lt;br&gt;
{&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Initialize(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; name,
System.Collections.Specialized.NameValueCollection config)&lt;br&gt;
{&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; MembershipUser
GetUser(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; username, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; userIsOnline)&lt;br&gt;
{&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Initialize is the easy but essential part - we need the connection string name for
later:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; connectionStringName;&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Initialize(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; name,
System.Collections.Specialized.NameValueCollection config)&lt;br&gt;
{&lt;br&gt;
connectionStringName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; config[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"connectionStringName"&lt;/span&gt;];&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;base&lt;/span&gt;.Initialize(name,
config);&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Now we can validate the user - well, the base class does that. We only do the auditing
part:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; ValidateUser(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; username, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; password)&lt;br&gt;
{&lt;br&gt;
HttpContext.Current.Trace.Write(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"ValidateUser:entry"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; bSuccess &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;base&lt;/span&gt;.ValidateUser(username,
password);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; connectionString &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;&lt;br&gt;
&lt;br&gt;
SqlConnection conn &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SqlConnection(connectionString);&lt;br&gt;
SqlCommand cmd &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SqlCommand(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"exec
myLogUserVisit @username, @success, @IP"&lt;/span&gt;, conn);&lt;br&gt;
&lt;br&gt;
cmd.Parameters.AddWithValue(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@username"&lt;/span&gt;,
username);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (bSuccess) 
&lt;br&gt;
&amp;nbsp; cmd.Parameters.AddWithValue(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@success"&lt;/span&gt;,
1);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp; cmd.Parameters.AddWithValue(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@success"&lt;/span&gt;,
0);&lt;br&gt;
&lt;br&gt;
cmd.Parameters.AddWithValue(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@IP"&lt;/span&gt;,
HttpContext.Current.Request.UserHostAddress);&lt;br&gt;
&lt;br&gt;
conn.Open();&lt;br&gt;
cmd.ExecuteNonQuery();&lt;br&gt;
conn.Close();&lt;br&gt;
&lt;br&gt;
HttpContext.Current.Trace.Write(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"ValidateUser:exit"&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; bSuccess;&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Step 4: Set it up - web.config&lt;/strong&gt;
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp; &amp;lt;appSettings/&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;connectionStrings&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="MyNWind" connectionString="Data Source=cbc05vpc\cbc05;Initial
Catalog=Northwind;User=sa;Password=P@ssw0rd"/&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/connectionStrings&amp;gt;&lt;br&gt;
&amp;nbsp; 
&lt;br&gt;
&amp;nbsp; &amp;lt;system.web&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;membership defaultProvider="SuperDuperMSProv"&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;providers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;clear/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name="SuperDuperMSProv" connectionStringName="MyNWind"
type="MyMembershipProvider"/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/providers&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/membership&amp;gt;&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Step 5: View the auditing information - default.aspx.cs&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The final "UI" looks like this:
&lt;/p&gt;
&lt;img src="http://chrison.net/content/binary/cbc05membershipprovider.png" border=0&gt; 
&lt;p&gt;
The source code is rather simple:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Page_Load(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
EventArgs e)&lt;br&gt;
{&lt;br&gt;
MyMembershipUser currentUser &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; (MyMembershipUser)Membership.GetUser();&lt;br&gt;
&lt;br&gt;
Label1.Text &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; currentUser.FullName;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; lcConnection &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; ConfigurationManager.ConnectionStrings[&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"MyNWind"&lt;/span&gt;].ConnectionString;&lt;br&gt;
&lt;br&gt;
SqlConnection conn &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SqlConnection(lcConnection);&lt;br&gt;
&lt;br&gt;
SqlCommand cmd &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SqlCommand(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"select
* from myLoginAuditing where username=@username"&lt;/span&gt;, conn);&lt;br&gt;
cmd.Parameters.AddWithValue(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"@Username"&lt;/span&gt;,
currentUser.UserName);&lt;br&gt;
&lt;br&gt;
conn.Open();&lt;br&gt;
&lt;br&gt;
SqlDataReader reader &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; cmd.ExecuteReader();&lt;br&gt;
&lt;br&gt;
GridView1.DataSource &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; reader;&lt;br&gt;
GridView1.DataBind();&lt;br&gt;
&lt;br&gt;
reader.Close();&lt;br&gt;
conn.Close();&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Done. By the way, did you notice something? Right! Alexander never fell into the trap
of SQL Injection.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://chrison.net/content/binary/ExtendingMembershipProviderDemo.zip"&gt;ExtendingMembershipProviderDemo.zip
(5.64 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://chrison.net/aggbug.ashx?id=c776faf3-471f-43f7-b19e-cdc0dcadff99" /&gt;</description>
      <comments>http://chrison.net/CommentView,guid,c776faf3-471f-43f7-b19e-cdc0dcadff99.aspx</comments>
      <category>2 Ohhhh</category>
      <category>ASP.NET</category>
      <category>Community</category>
      <category>Security</category>
    </item>
  </channel>
</rss>