<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <title>GrannetDotNet Blog</title>
    <link>http://blog.grannet.net/</link>
    <description>Personal web log of Grant Harmeyer</description>
    <dc:language>en-US</dc:language>
    <generator>this.Blog : GrannetDotNet Software</generator>
    <copyright>Copyright (C) 2010 GrannetDotNet Blog. All Rights Reserved.</copyright>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>GdnSwfObject Beta Release</title>
      <pubDate>Mon, 29 Jun 2009 19:31:31 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=183</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=183</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=183#FeedbackForm</comments>
      <slash:comments>0</slash:comments>
      <description>
        <![CDATA[
          <P>I&#39;ve released the beta for <A href="http://gdnswfobject.codeplex.com/" target=_blank>GdnSwfObject</A> that is now available for <A href="http://gdnswfobject.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28047" target=_blank>download</A> from <A href="http://www.codelex.com/" target=_blank>CodePlex</A>. This has really been a fun project for me since it is my first venture into the Open Source community. It&#39;s a low visibility project but the fact that it&#39;s getting a few downloads here and there is kind of cool :)</P>
<P>If you decide to use the GdnSwfObject server control, you can view the <A href="http://gdnswfobject.grannet.net/" target=_blank>API documentation</A> for instructions on how to use the control.</P>
<P>The final release of the control will be some time in July. This final release will include the new <A href="http://code.google.com/p/swfobject/" target=_blank>swfobject 2.2</A> runtime.</P>
        ]]>
      </description>
      <category>GdnSwfObject</category>
    </item>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>GdnSwfObject</title>
      <pubDate>Thu, 7 May 2009 20:13:33 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=182</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=182</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=182#FeedbackForm</comments>
      <slash:comments>0</slash:comments>
      <description>
        <![CDATA[
          <P>I&#39;ve recently posted my first open source project on <A href="http://www.codeplex.com" target=_blank>CodePlex</A>. <A href="http://gdnswfobject.codeplex.com/" target=_blank>GdnSwfObject</A> is an ASP.NET server control for placing Flash movies on ASP.NET pages using the great <A href="http://code.google.com/p/swfobject/" target=_blank>SWFObject</A> JavaScript technology. </P>
<P>If you feel like giving it a shot, pop on over the project at CodePlex and give it a whirl. </P>
        ]]>
      </description>
      <category>GdnSwfObject</category>
    </item>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>Exciting News from Redmond</title>
      <pubDate>Tue, 7 Oct 2008 16:20:49 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=181</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=181</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=181#FeedbackForm</comments>
      <slash:comments>0</slash:comments>
      <description>
        <![CDATA[
          <P>I am sure that many of you have already heard this, but <A href="http://www.microsoft.com/" target=_blank>Microsoft</A> is going to ship <A href="http://jquery.com/" target=_blank>jQuery</A> with <A href="http://www.asp.net/mvc/" target=_blank>ASP.NET 3.5 MVC</A>. This is HUGE for client development.</P>
<P>Read about <A href="http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx" target=_blank>some of the rationale</A> from <A href="http://weblogs.asp.net/scottgu/" target=_blank>the man</A> himself.</P>
        ]]>
      </description>
      <category>ASP.NET</category>
    </item>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>Around The Corner...</title>
      <pubDate>Mon, 19 May 2008 19:56:31 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=179</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=179</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=179#FeedbackForm</comments>
      <slash:comments>0</slash:comments>
      <description>
        <![CDATA[
          <P>I have recently become unsatisfied with the stale content that is on my website at <A href="http://www.grannet.net/" target=_blank>GrannetDotNet</A>. I have decided that it is time for a change of scenery: GrannetDotNet is going to be re-faced sometime soon. The content will be somewhat the same, but&nbsp;I hope to publish more&nbsp;syndicated content from a number of blog areas in the near future to place on this site.</P>
<P>That being said, I am in a bit of a dilemma also with my <A href="/" target=_blank>blog</A>. The current blog software that I use was written by myself and is several years old. There are many good blogging engines out there and I believe that I am going to use one of those. In a way, it is a sad thing to think about. This blog was the first piece of <A href="/BlogView.aspx?id=119" target=_blank>MeWare</A> that I ever wrote and I kind of hate to see it go. But, it has been a good blogging platform and hopefully I can maintain the history that is in this little personal&nbsp;Web outlet.</P>
<P>More to come soon...</P>
        ]]>
      </description>
      <category>Site News</category>
    </item>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>Google vs. Microsoft</title>
      <pubDate>Mon, 12 May 2008 10:11:35 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=178</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=178</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=178#FeedbackForm</comments>
      <slash:comments>0</slash:comments>
      <description>
        <![CDATA[
          <P><A href="http://blogs.techrepublic.com.com/hiner/" target=_blank>Jason Hiner</A> of <A href="http://techrepublic.com.com/" target=_blank>TechRepublic</A> today posted an <A href="http://blogs.techrepublic.com.com/hiner/?p=628" target=_blank>interesting message to his blog</A>&nbsp;about the recent happenings between Google, Microsoft and Yahoo. His post has some very interesting points, but a man by the name of Peter Buick from the UK posted a very interesting comment to the discussion of Hiner&#39;s blog posting. For more, please read: &#39;<A href="http://www.peterbuick.com/google/the-polite-street-mugger" target=_blank>The Polite Street Mugger</A>&#39; from <A href="http://www.peterbuick.com/" target=_blank>Buick&#39;s blog</A>.</P>
        ]]>
      </description>
      <category>Technology Thoughts</category>
    </item>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>The Many Uses of HTTP Handlers</title>
      <pubDate>Mon, 5 May 2008 23:5:14 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=177</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=177</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=177#FeedbackForm</comments>
      <slash:comments>0</slash:comments>
      <description>
        <![CDATA[
          <P>There are a number of instances in which you may need to handle file requests from your web applications in a custom fashion. HTTP Handlers provide us with a very easy to use means by which to extend our web applications to use ASP.NET to handle custom file types.</P>
<P><EM><A href="/Support/ImageGallery/HttpHandlers.zip"><STRONG>Click here to download the sample solution for this tutorial</STRONG></A></EM></P><STRONG>Creating a Simple Handler</STRONG> 
<P>In ASP.NET, an HTTP Handler is a means by which to process a specific endpoint request. Specifically, an HTTP Handler is used to process specific file types from within your ASP.NET website or application. The .NET Framework gives you a tremendous amount of flexibility and power when creating custom processing for specific HTTP requests. In ASP.NET, an HTTP Handler is any component that implements the <A href="http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.aspx" target=_blank>IHttpHandler</A> interface. The contract of this interface defines two key members: the <A href="http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.isreusable.aspx" target=_blank>IsReusable</A> property and the <A href="http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.processrequest.aspx" target=_blank>ProcessRequest</A> method.</P>
<UL>
<LI>IsReusable: Gets a value indicating whether another request can use the IHttpHandler instance 
<LI>ProcessRequest: Enables processing of custom HTTP requests. This is the heart of your custom HTTP Handler. The argument passed to this method is the <A href="http://msdn.microsoft.com/en-us/library/system.web.httpcontext.aspx" target=_blank>HttpContext</A> object of the current processing request.</LI></UL>
<P>Defining logic for these two members satisfies all that is necessary to create an HTTP Handler. When you have defined your handler, you will register the handler with the ASP.NET application using the &lt;httpHandlers /&gt; node of the Web.config. To register a handler, you must specify three attributes:</P>
<UL>
<LI>verb: This is the HTTP verb(s) that your handler will be used for when processing requests. The typical options are GET and POST 
<LI>path: This is the path of the file to process. In this instance, any file with an extension of .simple. 
<LI>type: The fully qualified type name of your HTTP Handler. In our example, this is SimpleHandler</LI></UL>
<P>After you have set up your web application using the above settings, you have successfully created and registered a custom HTTP Handler. </P>
<P>Now that you have an understanding of how HTTP Handlers work, let&#39;s do something a little fancier with our handler.</P><STRONG>Creating a More Complex Handler</STRONG> 
<P>In the previous example, we built an HTTP Handler that simply flushed text out to the browser. Although this may satisfy some requirements, most real world usage of HTTP Handlers will be more complex.</P>
<P>Since the HTTP Handler provides us with access to the current HttpContext, we have access to the current <A href="http://msdn.microsoft.com/en-us/library/system.web.httpresponse.aspx" target=_blank>HttpResponse</A> object as well. We can use this object to send specific file types to the client. We can also send entire files to the client with the addition of a single HTTP header. In our ComplexHandler example, we will configure the application to handle RSS requests to a blog, download Word documents and flush a custom file to the client, all from the same handler.</P>
<P>The RSS request queries my blog for the RSS feed. It then transforms that RSS feed using a custom XSL transformation to display on a page. This process could very easily be modified to use a custom RSS source or generate only the RSS rather than a transformation of the RSS.</P>
<P>As you can see, HTTP Handlers bring the power of ASP.NET processing to custom file types in an extremely useful way. </P>
        ]]>
      </description>
      <category>ASP.NET</category>
    </item>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>Microsoft and Web Standards</title>
      <pubDate>Fri, 2 Nov 2007 15:26:50 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=175</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=175</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=175#FeedbackForm</comments>
      <slash:comments>1</slash:comments>
      <description>
        <![CDATA[
          <P>Tony Patton is a clever guy who writes for <A href="http://www.techrepublic.com/" target=_blank>TechRepublic</A>. He writes the ASP.NET column that I read frequently and he recently posted an editorial titled: <A title="Permanent Link: When will Microsoft fully embrace Web standards?" href="http://blogs.techrepublic.com.com/programming-and-development/?p=530" target=_blank><EM>When will Microsoft fully embrace Web standards?</EM></A></P>
<P>His musing was targetted at specific Microsoft applications such as SharePoint 2007 and Outlook 2007. Although I partially agree with his points, I feel that he is missing the main point of distinction: SharePoint is an application - not the web.&nbsp;Shown below&nbsp;are my thoughts that I also posted to the discussion of the blog entry.</P>
<P><STRONG>Discussion Post:</STRONG></P>
<P>I really like Tony&#39;s columns, but this one has a few points which are not entirely related to one another.</P>
<P>SharePoint is not the web, nor is it simply a website. SharePoint is an application. It is a powerful and highly configurable application that integrates with desktop applications (MS Office), back office applications (Dynamics/CRM), mail servers (Exchange) and yes, even Internet Explorer. Since SharePoint sites/portals are generally secured to only company employees or partners, the environment in which they run is essentially controlled/contained. Unfortunately, much of the integration required by this application is beyond the scope of W3C standards. That doesn&#39;t justify the point, but it does clarify it a bit.</P>
<P>Given their past, I know that it is easy to vilify Microsoft in the quest for a standard web. But Tony touched on Microsoft&#39;s effort with his mentioning of the rich standards support in VS2005 and Expression Web. The HTML editor in VS2005 will tell you if you are using an element or attribute that is out-dated or deprecated from the current standard. You can also choose to have your entire site examined for WCAG and if you have a violation of WCAG, it will tell you the WCAG section as well as instruct you as to&nbsp;what you must do to correct it. Also, all Microsoft provided ASP.NET 2.0 server controls emit standards compliant markup.</P>
<P>The bottom line is this; SharePoint and Outlook are applications - not the web. Although they use HTML, there is a significant difference. Standards have their place and are a very good thing, and when it comes to providing standards compliant tools for developers, Microsoft has made tremendous improvements.</P>
        ]]>
      </description>
      <category>Technology Thoughts</category>
    </item>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>IIS Is Gaining Significant Web Server Market Share</title>
      <pubDate>Mon, 20 Aug 2007 11:33:55 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=174</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=174</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=174#FeedbackForm</comments>
      <slash:comments>0</slash:comments>
      <description>
        <![CDATA[
          <P>I must be honest, I believe that the <A href="http://en.wikipedia.org/wiki/Apache_HTTP_Server" target=_blank>Apache web server</A> and <A href="http://en.wikipedia.org/wiki/Open-source_software" target=_blank>Open-source</A> technologies such as <A href="http://en.wikipedia.org/wiki/Linux" target=_blank>Linux</A>, <A href="http://en.wikipedia.org/wiki/PHP" target=_blank>PHP</A> and <A href="http://en.wikipedia.org/wiki/MySQL" target=_blank>MySQL</A> (a bundle known as <A href="http://en.wikipedia.org/wiki/LAMP_%28software_bundle%29" target=_blank>LAMP</A>) will, most likely, always possess&nbsp;the largest market share of the web server market. The constituency of LAMP admins/users/developers consists of high numbers and unparallelled loyalty, but a <A href="http://blogs.techrepublic.com.com/tech-news/?p=1041" target=_blank>recent blog entry</A> on TechRepublic cited a recent survey that indicates the LAMP market share is&nbsp;losing ground&nbsp;significantly to&nbsp;<A href="http://en.wikipedia.org/wiki/IIS" target=_blank>Microsoft IIS</A>.</P>
<P>I have been developing ASP Classic/ASP.NET applications on the IIS platform for 6 years now. I started with IIS5 on Win2K server. The product was good, but the advancements made in the last few years that embrace the <A href="http://en.wikipedia.org/wiki/NET_Framework" target=_blank>.NET Framework</A> have truly been amazing. ASP.NET, now in version 2.0, has taken web development to a level that I would have never imagined possible. It is no wonder that some open source guys (including <A href="http://www.eecs.mit.edu/" target=_blank>MIT</A>, where open source was born) are making statements like this:</P>
<P><EM>ASP.NET 2.0 is a much more viable platform for sophisticated apps than it used to be. MIT recently switched from java to C# for 1st year developers and I see .NET as much as J2EE in app jobs. As well, when I go to more sophisticated sites there are alot more .aspx is the URLs these days.</EM></P>
<P>It&#39;s taken a number of years for this to happen, but through a few versions of the technology, the .NET Framework&nbsp;it is gaining a level of sophistication and maturity that developers can no longer deny. The fact that the underlying platform is built to run hand-in-hand with IIS is most likely the largest cause for this recent change of market share in the web server market.</P>
        ]]>
      </description>
      <category>Technology Thoughts</category>
    </item>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>The Dark Knight</title>
      <pubDate>Sun, 29 Jul 2007 9:25:50 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=173</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=173</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=173#FeedbackForm</comments>
      <slash:comments>0</slash:comments>
      <description>
        <![CDATA[
          <P>For those of you (myself included) who thought that <A href="http://imdb.com/title/tt0372784/" target=_blank>Batman Begins</A>&nbsp;was one of the best <A href="http://en.wikipedia.org/wiki/Batman" target=_blank>Batman</A> movies to this point, you&#39;ll be happy to know that the next Batman flick is now filming. This may be old news to a lot of you, but I just stumbled across it.</P>
<P>The title is <A href="http://imdb.com/title/tt0468569/" target=_blank>The Dark Knight</A> and it once again stars <A href="http://imdb.com/name/nm0000288/" target=_blank>Christian Bale</A> as Batman/Bruce Wayne, and <A href="http://imdb.com/name/nm0005132/" target=_blank>Heath Ledger</A> will play the villain as <A href="http://en.wikipedia.org/wiki/The_Joker" target=_blank>The Joker</A>. Batman has always been one of my favorite comic book characters simply because he possesses no super-human powers to rely upon. I don&#39;t know, it kind of makes the story a bit more attractive.</P>
<P>I personally cannot wait to see how this movie plays out!</P>
        ]]>
      </description>
      <category>Random Thoughts</category>
    </item>
    <item>
      <dc:creator>Grant Harmeyer</dc:creator>
      <title>Dynamic Themes and META Data using ASP.NET 2.0 Master Pages</title>
      <pubDate>Thu, 17 May 2007 8:8:16 EST</pubDate>
      <link>http://blog.grannet.net/BlogView.aspx?id=171</link>
      <guid>http://blog.grannet.net/BlogView.aspx?id=171</guid>
      <comments>http://blog.grannet.net/BlogView.aspx?id=171#FeedbackForm</comments>
      <slash:comments>0</slash:comments>
      <description>
        <![CDATA[
          <P>ASP.NET 2.0 introduced two pieces of functionality that Web application developers have been thirsting for since ASP.NET was first created: Themes and Master Pages. As with any new technology, there are a few caveats that make the default implementation of these new technologies slightly less than ideal. In this tutorial, I will explain a very straightforward way to implement Master Pages and Themes to allow the user to select a theme as well as how to place META data in the header of a Master Page without CodeBehind. </P>
<P><EM>Download Solution:&nbsp;</EM><A href="http://www.grannet.net/Support/blog.grannet.net/AspNetMasterPages/_05_2007_MasterPages.zip"><EM>_05_2007_MasterPages.zip</EM></A><EM> (16.0KB)</EM></P><STRONG>Part 1: Implementing a Dynamic Theme Mechanism</STRONG> 
<P>Allowing users to select their own theme for your Web application is a feature that is gaining large amounts of popularity amongst users. ASP.NET 2.0 offers many ways to accomplish a theme implementation for your website, such as specifying a theme name in the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="BACKGROUND: yellow">&lt;%</SPAN><SPAN style="COLOR: blue">@</SPAN><SPAN style="COLOR: maroon"> Page </SPAN><SPAN style="BACKGROUND: yellow">%&gt;</SPAN></SPAN> directive of a Web Form, specifying a <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> in the Web.config file for your application or setting the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> property of the <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">Page</SPAN> class. All of these options provide a great way for administrators to apply themes to their apps, but there are some significant drawbacks to each: </P>
<UL>
<LI>Specifying a theme name in the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="BACKGROUND: yellow">&lt;%</SPAN><SPAN style="COLOR: blue">@</SPAN><SPAN style="COLOR: maroon"> Page </SPAN><SPAN style="BACKGROUND: yellow">%&gt;</SPAN></SPAN> directive of each Web Form is a nightmare from a maintainability standpoint. In Web apps that may have hundreds of Pages, you would have to update the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> attribute in every Web Form. 
<LI>Storing the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> in the <SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &#39;Courier New&#39;">&lt;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: &#39;Courier New&#39;">pages</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &#39;Courier New&#39;">/&gt;</SPAN> element of the Web.config file solves the issue of having to update each page individually, but it also comes with its own baggage. If you use the <EM>Publish Web Site</EM> option in Visual Studio 2005, VS will hard-code the theme name into the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> attribute of the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="BACKGROUND: yellow">&lt;%</SPAN><SPAN style="COLOR: blue">@</SPAN><SPAN style="COLOR: maroon"> Page </SPAN><SPAN style="BACKGROUND: yellow">%&gt;</SPAN></SPAN> directive on all pages that have any CodeBehind specified. If you then later change the name of the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> in the Web.config file, all ASPX content pages will reflect the change, but any pages with CodeBehind .dll files in the Bin directory of your app will still use the theme that was specified in the Web.config when you published the site. Also, changing the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> in the Web.config will cause IIS to recycle the application. Again, this is less than ideal. 
<LI>Finally, setting the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> programmatically by setting the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> property of the <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">Page</SPAN> is a pretty appetizing solution. Unfortunately, a <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> is applied to an ASP.NET Web Form very early in execution, so you must do so before the <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">Page</SPAN> initializes. This is typically handled in a <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">PreInit</SPAN> event handler for a page. Furthermore, this requires you to create this event handler in every page of your application that uses your <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN>. </LI></UL>
<P>I know what many of you are saying: Why can&#39;t I just specify a <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">PreInit</SPAN> event handler in the <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">MasterPage</SPAN> that is used by all of my pages? Unfortunately this does not work because the <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">MasterPage</SPAN> is first compiled, then applied to the Page. The <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">Page</SPAN> class sets the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> after the <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">MasterPage</SPAN> has already been applied, thus we are once again stuck. </P>
<P>I have seen many posts on forums that show how to accomplish this through a rather lengthy process of using an <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">HttpModule</SPAN> to set the theme. While this solution works fine, it&#39;s a bit of an over complication. To solve this issue we need look no further than one of the most useful techniques in object oriented programming: Inheritance. </P>
<P>By deriving a class from the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">System.Web.UI.<SPAN style="COLOR: teal">Page</SPAN></SPAN> class, we are able to create the functionality necessary to give our users a theme rich experience with a simple event handler. In this example, I am using a class named <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">AppCookie</SPAN> to store the theme name and <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">AppPageBase</SPAN> is my <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">Page</SPAN> derived class. The <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> property of the <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">AppCookie</SPAN> class is read from a <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">PreInit</SPAN> event handler that is subscribed to the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">PreInit</SPAN> event from the body of the <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">AppPageBase</SPAN> constructor.</P>
<P>The event handler body is somewhat simple. A new instance of an <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">AppCookie</SPAN> is created and tested to see if the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Theme</SPAN> property is empty. If the property is not empty, the specified theme is applied to the page. If it is empty, the default theme which is defined in the <SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &#39;Courier New&#39;">&lt;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: &#39;Courier New&#39;">appSettings</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &#39;Courier New&#39;">/&gt;</SPAN> element of my Web.config file is applied instead. </P>
<P>The last step of the process is to ensure that all pages in the application use our <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">AppPageBase</SPAN> class as the base type for all ASP.NET pages. To do so, we change the inherited class on all CodeBehind class definitions to that of our custom class. We must also change the page base type for all pages in the application that may not use CodeBehind. To accomplish this, specify the <SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: &#39;Courier New&#39;">pageBaseType</SPAN> attribute of the <SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &#39;Courier New&#39;">&lt;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: &#39;Courier New&#39;">pages</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &#39;Courier New&#39;">/&gt;</SPAN> element to be the name of our custom class. Finally, I then added a few <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="COLOR: blue">&lt;</SPAN><SPAN style="COLOR: maroon">asp</SPAN><SPAN style="COLOR: blue">:</SPAN><SPAN style="COLOR: maroon">LinkButton</SPAN> <SPAN style="COLOR: blue">/&gt;</SPAN></SPAN> controls to a Web Form to allow the switching between themes to be done by the user. </P>
<P>This implementation allows the user to control the theme, but could very easily be modified to allow only administrators to control the theme. You could store the selected theme in a text or XML file, or use the Web Configuration API to change the value of the default theme in our app settings. If an <EM>admin only</EM> theme scenario is what you are facing, I would recommend using an external file to store the selected theme. This way IIS will not restart your app every time you make a theme change, as it would if this data was stored in the Web.config.</P>
<P><EM>Code for Part 1: </EM><A href="http://www.grannet.net/Support/blog.grannet.net/AspNetMasterPages/HtmDocs/AppCookie.htm" target=_CodeListing><EM>AppCookie</EM></A><EM>, </EM><A href="http://www.grannet.net/Support/blog.grannet.net/AspNetMasterPages/HtmDocs/AppPageBase_A.htm" target=_CodeListing><EM>AppPageBase</EM></A><EM>&nbsp;(A), </EM><A href="http://www.grannet.net/Support/blog.grannet.net/AspNetMasterPages/HtmDocs/WebConfig.htm" target=_CodeListing><EM>Web.config</EM></A>&nbsp;</P><STRONG>Part 2: META Data in Master Pages</STRONG> 
<P>Although META data in the <SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &#39;Courier New&#39;">&lt;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: &#39;Courier New&#39;">head</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="COLOR: blue">/&gt;</SPAN></SPAN> of an HTML document does not carry as much weight with regard to search engines as it once did, it is still a valuable compliment to any Search Engine Optimization strategy. Unfortunately, when using a <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">MasterPage</SPAN> in ASP.NET 2.0, we lose our declarative control over META data and must rely on programmatic alternatives. Adding a META tag to a Web Form that uses a <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">MasterPage</SPAN> is accomplished by creating an instance of a <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">System.Web.UI.HtmlControls.<SPAN style="COLOR: teal">HtmlMeta</SPAN></SPAN> object, assigning values to its properties and then adding it to the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Controls</SPAN> collection of the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Page.Header</SPAN> control. Obviously, this becomes troublesome when using a <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">MasterPage</SPAN> on a Web Form that is only a content page and has no CodeBehind to perform this operation. Luckily, our <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">AppPageBase</SPAN> can be extended to give us the ability to enter META data directly into the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="BACKGROUND: yellow">&lt;%</SPAN><SPAN style="COLOR: blue">@</SPAN><SPAN style="COLOR: maroon"> Page </SPAN><SPAN style="BACKGROUND: yellow">%&gt;</SPAN></SPAN> directive. </P>
<P>In our example we are creating two properties in our <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">AppPageBase</SPAN> class; <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">MetaDescription</SPAN> and <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">MetaKeywords</SPAN>. These are simple string values that will be used to store description and keyword data. To output these values to the page, we will create and attach an event handler to the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">Init</SPAN> event of the <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">Page</SPAN> in the same manner as before. The body of the event handler will create an instance of an <SPAN style="FONT-SIZE: 10pt; COLOR: teal; FONT-FAMILY: &#39;Courier New&#39;">HtmlMeta</SPAN> object and use the two properties defined earlier to add this to the <SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &#39;Courier New&#39;">&lt;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: &#39;Courier New&#39;">head</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="COLOR: blue">/&gt;</SPAN></SPAN> of the resultant HTML output. Finally, we specify the values for the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">MetaDescription</SPAN> and the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">MetaKeywords</SPAN> as attributes of the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="BACKGROUND: yellow">&lt;%</SPAN><SPAN style="COLOR: blue">@</SPAN><SPAN style="COLOR: maroon"> Page </SPAN><SPAN style="BACKGROUND: yellow">%&gt;</SPAN></SPAN> directive for the Web Form. </P>
<P>If you view the pages, you will see that the theme is applied based on user selection. You&#39;ll also note by viewing the source code for page <EM>NoCodeBehind.aspx</EM> that the META data was properly added to the <SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: &#39;Courier New&#39;">&lt;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: &#39;Courier New&#39;">head</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="COLOR: blue">/&gt;</SPAN></SPAN> of the document without any CodeBehind.</P>
<P><EM>Code for Part 2: </EM><A href="http://www.grannet.net/Support/blog.grannet.net/AspNetMasterPages/HtmDocs/AppCookie.htm" target=_CodeListing><EM>AppCookie</EM></A><EM>, </EM><A href="http://www.grannet.net/Support/blog.grannet.net/AspNetMasterPages/HtmDocs/AppPageBase_B.htm" target=_CodeListing><EM>AppPageBase</EM></A><EM>&nbsp;(B), </EM><A href="http://www.grannet.net/Support/blog.grannet.net/AspNetMasterPages/HtmDocs/WebConfig.htm" target=_CodeListing><EM>Web.config</EM></A>&nbsp;</P>
<P>In closing, you can see where these two techniques can perform leaps and bounds in the maintenance of an ASP.NET 2.0 Web application. An important note: if you have an ASP.NET content page that you do not wish to be themed in your application, simply specify <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;">System.Web.UI.<SPAN style="COLOR: teal">Page</SPAN></SPAN> as the value of the <SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: &#39;Courier New&#39;">Inherits</SPAN> attribute of the <SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: &#39;Courier New&#39;"><SPAN style="BACKGROUND: yellow">&lt;%</SPAN><SPAN style="COLOR: blue">@</SPAN><SPAN style="COLOR: maroon"> Page </SPAN><SPAN style="BACKGROUND: yellow">%&gt;</SPAN></SPAN> directive. This will override the base type from the Web.config. Also note that this article did not cover caching of user defined themed pages. If you wish to explore your caching options, read&nbsp;the&nbsp;<A href="http://msdn2.microsoft.com/en-us/library/ms178597(vs.80).aspx" target=_msdn>ASP.NET Caching Overview</A> on <A href="http://msdn2.microsoft.com/en-us/default.aspx" target=_msdn>MSDN</A>.&nbsp;</P>
        ]]>
      </description>
      <category>ASP.NET</category>
    </item>
  </channel>
</rss>