<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" 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:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>C#/Development</title>
        <link>http://ryanfarley.com/blog/category/8.aspx</link>
        <description>C#/Development</description>
        <language>en-US</language>
        <copyright>Ryan Farley</copyright>
        <managingEditor>ryan.farley@customerfx.com</managingEditor>
        <generator>Subtext Version 1.9.5.177</generator>
        <item>
            <title>Using Google Docs as an Online Database</title>
            <link>http://ryanfarley.com/blog/archive/2010/09/24/using-google-docs-as-an-online-database.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbffe71803000000ae00000001000500&lt;/div&gt;From time to time I throw a website together for some temporary purpose. The website collects some data from users and I need to make this data available for whoever I put the site together for. A perfect example of this is a website that I put together for my wife for some craft making event. She needed to allow friends to place orders for various craft activities so she knew what materials she needed to order. She needed to be able to see these orders as they were placed. For a website like this, my goal is to do it with as little effort and as quick as possible. It's for a temporary purpose anyway. A great way to do this is to use Google Docs as the back end for storing the data.  &lt;br /&gt;  &lt;br /&gt;Some of the immediate benefits of using Google Docs rather than a database are:  &lt;br /&gt;  &lt;ol&gt;   &lt;li&gt;No need to use a hosting account that supports some database or document storage &lt;/li&gt;    &lt;li&gt;No need to create any tables or schema of any kind as well as a data model     &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;I can still build my own nice looking form &amp;amp; webpage &lt;/li&gt;    &lt;li&gt;I don't need to build anything to view the collected data. This is the best part. In the scenario I mentioned about building a craft ordering website for my wife, I can create the spreadsheet right in her Google Docs (I could also create it in mine and share with her). &lt;/li&gt;    &lt;li&gt;I can use built in features in Google Docs such as having it e-mail me when changes are made to the file (or as a daily digest). I could notify my wife of orders without writing any code to do so. &lt;/li&gt; &lt;/ol&gt; Now, with a spreadsheet on Google Docs, you do have the ability to make quicky forms, like you do in Access, but that is not what I am talking about here. In my scenario, I am using a Google Docs spreadsheet simply as a back end database for holding the collected data. I still want to make my own ASP.NET webpage &amp;amp; form, I just don't want to have to deal with the "data" itself.  &lt;br /&gt;  &lt;br /&gt;Writing the code using the GData API is not that hard. It's really pretty easy. However, I came across something for this sort of thing that does make it even easier. There is an open source project on github by Mauricio Scheffer called GDataDB. This is a library that makes inserting, updating, or retrieving data or any kind in a spreadsheet on Google Docs just as easy as using a database repository. Incredibly easy.  &lt;br /&gt;  &lt;br /&gt;  &lt;div class="link"&gt;&lt;a href="http://github.com/mausch/GDataDB"&gt;Take a look at the GDataDB repository on github&lt;/a&gt;&lt;/div&gt;  &lt;br /&gt;Here's how GDataDB works. You basically just create your own POCO objects to hold your data. Then GDataDB will handle the rest, including the creation of the spreadsheet if you want it to. Let's consider this "Person" POCO that will represent the data I am collecting:  &lt;br /&gt;  &lt;br /&gt;  &lt;pre&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; Person
{
    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; FirstName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; LastName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Email { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Phone { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public&lt;/span&gt; DateTime DateOfBirth { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; NumberOfKids { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;

&lt;br /&gt;Now, I can use this object to add the data like this:

&lt;br /&gt;

&lt;br /&gt;

&lt;pre&gt;&lt;span style="color: green"&gt;//using GDataDB; 
//...
&lt;/span&gt; 
 
&lt;span style="color: green"&gt;// create the DatabaseClient passing my Gmail or Google Apps credentials
&lt;/span&gt;IDatabaseClient client &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; DatabaseClient(&lt;span style="color: #008080"&gt;"user@gmail.com"&lt;/span&gt;, &lt;span style="color: #008080"&gt;"password"&lt;/span&gt;);
 
&lt;span style="color: green"&gt;// get or create the database. This is the spreadsheet file 
&lt;/span&gt;IDatabase db &lt;span style="color: navy"&gt;=&lt;/span&gt; client.GetDatabase(MyFileName) ?? client.CreateDatabase(MyFileName);
 
&lt;span style="color: green"&gt;// get or create the table. This is a worksheet in the file 
// note I am using my Person object so it knows what my schema needs to be  
// for my data. It will create a header row with the property names 
&lt;/span&gt;ITable&amp;lt;Person&amp;gt; table &lt;span style="color: navy"&gt;=&lt;/span&gt; db.GetTable&amp;lt;Person&amp;gt;(MySheetName) ?? db.CreateTable&amp;lt;Person&amp;gt;(MySheetName);
 
&lt;span style="color: green"&gt;// now I can fill a Person object and add it
&lt;/span&gt;var person &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; Person();
person.FirstName &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: #008080"&gt;"Ryan"&lt;/span&gt;;
person.LastName &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: #008080"&gt;"Farley"&lt;/span&gt;;
person.Email &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: #008080"&gt;"me@me.com"&lt;/span&gt;;
&lt;span style="color: green"&gt;//...
&lt;/span&gt; 
table.Add(person);&lt;/pre&gt;

&lt;br /&gt;Pretty easy stuff. Locating a row for editing is just as easy. Lets say using the same Person object I want to locate an existing row based on the Email property and if it exists I want to update that row, otherwise add a new row.

&lt;br /&gt;

&lt;br /&gt;

&lt;pre&gt;&lt;span style="color: green"&gt;//using GDataDB;
//...
&lt;/span&gt; 
 
IDatabaseClient client &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; DatabaseClient(&lt;span style="color: #008080"&gt;"user@gmail.com"&lt;/span&gt;, &lt;span style="color: #008080"&gt;"password"&lt;/span&gt;);
IDatabase db &lt;span style="color: navy"&gt;=&lt;/span&gt; client.GetDatabase(MyFileName) ?? client.CreateDatabase(MyFileName);
ITable&amp;lt;Person&amp;gt; table &lt;span style="color: navy"&gt;=&lt;/span&gt; db.GetTable&amp;lt;Person&amp;gt;(MySheetName) ?? db.CreateTable&amp;lt;Person&amp;gt;(MySheetName);
 
&lt;span style="color: green"&gt;// now I can fill a Person object and add it
&lt;/span&gt;var person &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; Person();
person.FirstName &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: #008080"&gt;"Ryan"&lt;/span&gt;;
person.LastName &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: #008080"&gt;"Farley"&lt;/span&gt;;
person.Email &lt;span style="color: navy"&gt;=&lt;/span&gt; &lt;span style="color: #008080"&gt;"me@me.com"&lt;/span&gt;;
&lt;span style="color: green"&gt;//...
&lt;/span&gt; 
&lt;span style="color: green"&gt;// see if row exists first by matching on Email
&lt;/span&gt;IList&amp;lt;IRow&amp;lt;Person&amp;gt;&amp;gt; rows &lt;span style="color: navy"&gt;=&lt;/span&gt; table.FindStructured(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format("username=\"{0}\", person.Email));
&lt;span style="color: blue"&gt;if&lt;/span&gt; (rows == &lt;span style="color: blue"&gt;null&lt;/span&gt; || rows.Count == 0)
{
    &lt;span style="color: green"&gt;// Email does not exist yet, add row
&lt;/span&gt;    table.Add(person);
}
&lt;span style="color: blue"&gt;else&lt;/span&gt;
{
    &lt;span style="color: green"&gt;// Email was located, edit the row with the new data
&lt;/span&gt;    IRow&amp;lt;Person&amp;gt; row &lt;span style="color: navy"&gt;=&lt;/span&gt; rows[0];
    row.Element &lt;span style="color: navy"&gt;=&lt;/span&gt; person;
    row.Update();
}&lt;/pre&gt;

&lt;br /&gt;Look ma, no SQL. Sure, there are other options out there that I could use, such as Mongo or whatever, but using Google Docs requires nothing, no setup, no anything. My wife can already see the data and tweak it if needed. I didn't have to build that. She also can get notification e-mails when someone uses the webpage to add data to the spreadsheet. I didn't have to build that. I am just working with my POCO objects, just a couple short lines of code and I can add that to the spreadsheet via GData. I didn't have to build that, GDataDB did it for me. Pretty quick and easy. I like it.


&lt;img src="http://ryanfarley.com/blog/aggbug/38139.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2010/09/24/using-google-docs-as-an-online-database.aspx</guid>
            <pubDate>Fri, 24 Sep 2010 08:15:23 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2010/09/24/using-google-docs-as-an-online-database.aspx#feedback</comments>
            <slash:comments>29</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38139.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38139.aspx</trackback:ping>
        </item>
        <item>
            <title>Announcing the Growl for Windows Target for NLog (and another reason to love Growl)</title>
            <link>http://ryanfarley.com/blog/archive/2010/05/06/announcing-the-growl-for-windows-target-for-nlog.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbff385d02000000ab00000001000600&lt;/div&gt;I love &lt;a href="http://www.growlforwindows.com/" target="_blank"&gt;Growl&lt;/a&gt;. In my opinion it is something that should be built into the OS and I wish that every app supported sending Growl notifications. Lately I have been using Growl to get notifications from my own applications. This has been a great way to get instant feedback from applications while testing or when problems happen. However, instead of building in support for Growl, I add these notifications via a custom target for NLog so the notifications are configurable as part of the logging solution.&lt;br /&gt;
&lt;br /&gt;
&lt;font size="4"&gt;&lt;span style="font-weight: bold;"&gt;What is Growl for Windows?&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
First of all, for those who are not familiar with what Growl is, you're missing out. Take a look at Growl's &lt;a target="_blank" href="http://www.growlforwindows.com/gfw/about.aspx"&gt;About page&lt;/a&gt; to find out more. Basically, it is a Windows version of the Mac growl notification system that displays notifications using the GNTP protocol. Growl gives you notifications when things happen. It can be something from your machine or something on some other machine on the network. Think of it as a uniform notification system that any application can use.&lt;br /&gt;
&lt;br /&gt;
&lt;font size="4"&gt;&lt;span style="font-weight: bold;"&gt;Using Growl as a Logging Notification Target&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
So, back to my original topic. I use &lt;a href="http://nlog-project.org/" target="_blank"&gt;NLog&lt;/a&gt; for logging. For logging, NLog is awesome (why I prefer it to log4net will require another post). Some of the things that make Growl for a logging target useful for me:&lt;br /&gt;
&lt;ol&gt;
    &lt;li&gt;Instant feedback while testing applications. I can get details about what is going on in my application while testing, whether I am debugging or not by simply turning on my Growl target in the NLog.config file.&lt;/li&gt;
    &lt;li&gt;If the application is running on a server, I can have the application send fatal or error logging notifications right to my desktop. If my server app has a fatal problem it will get logged, but I get the instant feedback with a Growl notification on my desktop.&lt;/li&gt;
&lt;/ol&gt;
&lt;font size="4"&gt;&lt;span style="font-weight: bold;"&gt;The custom GrowlNotify target for NLog&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
Let's take a look at my simple custom NLog logging target for Growl. To use the GrowlNotify target in NLog, all you have to do is &lt;a href="http://github.com/downloads/RyanFarley/NLogGrowlNotify/NLog.Targets.GrowlNotify_Binaries.zip"&gt;download the GrowlNotify binaries&lt;/a&gt;, place them in the same folder as your app (no need to add them as references, just put them where the NLog.dll and NLog.config are), then wire it up as a target in the NLog.config file. Here is a sample configuration for using the GrowlNotify target:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;lt;?xml version=&lt;span style="color: rgb(0, 128, 128);"&gt;"1.0"&lt;/span&gt; encoding=&lt;span style="color: rgb(0, 128, 128);"&gt;"utf-8"&lt;/span&gt; ?&amp;gt;&lt;br /&gt;&amp;lt;nlog xmlns=&lt;span style="color: rgb(0, 128, 128);"&gt;"http://www.nlog-project.org/schemas/NLog.xsd"&lt;br /&gt;&lt;/span&gt;      xmlns:xsi=&lt;span style="color: rgb(0, 128, 128);"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&amp;gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;extensions&amp;gt;&lt;br /&gt;        &amp;lt;add assembly=&lt;span style="color: rgb(0, 128, 128);"&gt;"NLog.Targets.GrowlNotify"&lt;/span&gt; &lt;span style="color: Navy;"&gt;/&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/extensions&amp;gt;&lt;br /&gt;     &lt;br /&gt;    &amp;lt;targets&amp;gt;&lt;br /&gt;        &amp;lt;target name=&lt;span style="color: rgb(0, 128, 128);"&gt;"growl"&lt;/span&gt; type=&lt;span style="color: rgb(0, 128, 128);"&gt;"GrowlNotify"&lt;/span&gt; password=&lt;span style="color: rgb(0, 128, 128);"&gt;""&lt;/span&gt; host=&lt;span style="color: rgb(0, 128, 128);"&gt;""&lt;/span&gt; port=&lt;span style="color: rgb(0, 128, 128);"&gt;""&lt;/span&gt; &lt;span style="color: Navy;"&gt;/&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/targets&amp;gt;&lt;br /&gt; &lt;br /&gt;    &amp;lt;rules&amp;gt;&lt;br /&gt;        &amp;lt;logger name=&lt;span style="color: rgb(0, 128, 128);"&gt;"*"&lt;/span&gt; minLevel=&lt;span style="color: rgb(0, 128, 128);"&gt;"Trace"&lt;/span&gt; appendTo=&lt;span style="color: rgb(0, 128, 128);"&gt;"growl"&lt;/span&gt;&lt;span style="color: Navy;"&gt;/&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/rules&amp;gt;&lt;br /&gt; &lt;br /&gt;&amp;lt;/nlog&amp;gt;&lt;/pre&gt;
&lt;br /&gt;
That configuration will send any level of logging event to Growl on the same/local machine. To have the Growl notification sent over the network, all you have to do is fill in the parameters for "password", "host" (with a machine name or IP address), and optionally the "port" (if you've changed your Growl port from the default). That is it. &lt;br /&gt;
&lt;br /&gt;
Each logging level has it's own icon. Here's some screenshots of NLog GrowlNotify in action:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://content.screencast.com/users/RyanFarley/folders/Private/media/1a42ddb1-86c4-4a83-b91a-6b97d811ec40/GrowlNotify_Registration.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://content.screencast.com/users/RyanFarley/folders/Private/media/fdabad11-7630-4af6-bda5-c928a8927d5e/GrowlNotify_Trace.png" /&gt;      &lt;img alt="" src="http://content.screencast.com/users/RyanFarley/folders/Private/media/208edad0-e158-4fde-8c7b-d8cd180ffe3b/GrowlNotify_Debug.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://content.screencast.com/users/RyanFarley/folders/Private/media/aad65380-0539-4b39-8982-17e60fb81bfe/GrowlNotify_Info.png" /&gt;      &lt;img alt="" src="http://content.screencast.com/users/RyanFarley/folders/Private/media/2e4fe6a2-2954-4ad0-85c7-19397129f90b/GrowlNotify_Warn.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://content.screencast.com/users/RyanFarley/folders/Private/media/0bc73285-487b-4c98-bad1-c5eeed7e4c04/GrowlNotify_Error.png" /&gt;      &lt;img alt="" src="http://content.screencast.com/users/RyanFarley/folders/Private/media/17187701-1142-452a-a127-30a96ebfd7b9/GrowlNotify_Fatal.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
Of course, once you've used GrowlNotify once and the DLL has registered itself with Growl, you'll be able to tweak things for each notification level in the Growl applications list, such as making the more critical levels play a different sound, etc:&lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://content.screencast.com/users/RyanFarley/folders/Jing/media/3bae7a36-0dec-4a34-8a8f-031b6a3e93cc/Growl-NLogSettings.png" alt="" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="link"&gt;To grab the source for NLog GrowlNotify, head over to the &lt;strong&gt;&lt;a target="_blank" href="http://github.com/RyanFarley/NLogGrowlNotify"&gt;repository on Github&lt;/a&gt;&lt;/strong&gt;.&lt;/div&gt;&lt;img src="http://ryanfarley.com/blog/aggbug/38138.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2010/05/06/announcing-the-growl-for-windows-target-for-nlog.aspx</guid>
            <pubDate>Thu, 06 May 2010 19:57:09 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2010/05/06/announcing-the-growl-for-windows-target-for-nlog.aspx#feedback</comments>
            <slash:comments>19</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38138.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38138.aspx</trackback:ping>
        </item>
        <item>
            <title>Sign a .NET Assembly with a Strong Name Without Recompiling</title>
            <link>http://ryanfarley.com/blog/archive/2010/04/23/sign-a-.net-assembly-with-a-strong-name-without-recompiling.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbff4d4e02000000ad00000001000500&lt;/div&gt;Signing a .NET assembly with a strong name is easy in Visual Studio. However, what if this is a 3rd party assembly and you don't have the source?&lt;br /&gt;
&lt;br /&gt;
For me, I have an application that has a requirement that all assemblies are signed with a strong name. One of the assemblies I am using is &lt;a target="_blank" href="http://restsharp.org/"&gt;RestSharp&lt;/a&gt;. I like to contribute to RestSharp and I didn't want to modify the project file to sign the assembly as I didn't want that to go back to the repository when I had some changes to contribute. &lt;br /&gt;
&lt;br /&gt;
Not a problem. What I have is a batch file that disassembles the DLL to IL and then reassembles the IL back into a DLL and includes my key file. This way I get to keep the original DLL for projects that I don't need the assembly to have a strong name and a separate one that is signed with the strong name for the projects where I need that.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Here's what I did:&lt;/span&gt;&lt;br /&gt;
&lt;ol&gt;
    &lt;li&gt;In the Release build folder I created the following:
    &lt;ul&gt;
        &lt;li&gt;The key file (create using &lt;tt&gt;sn.exe -k MyPublicPrivateKeyFile.snk&lt;/tt&gt;)&lt;/li&gt;
        &lt;li&gt;A subfolder to contain the signed assembly, mine is named "Signed"&lt;br /&gt;
        &lt;/li&gt;
        &lt;li&gt;A batch file (see below)&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Create a batch file in the Release folder named "SignAssembly.bat" with the following contents:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;del .\Signed\RestSharp.* /F&lt;br /&gt;"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\ildasm.exe" .\RestSharp.dll /out:.\Signed\RestSharp.il&lt;br /&gt;"C:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe" .\Signed\RestSharp.il /dll /key=.\RestSharp.snk /output=.\Signed\RestSharp.dll&lt;br /&gt;&lt;br /&gt;pause&lt;/pre&gt;
The first line deletes any previously signed assembly. Second line uses ILDASM to disassemble the DLL to IL in the "Signed" folder as RestSharp.il. The third line reassembles the IL into an assembly using ILASM and tells it to use the IL file and the key file. That's it.&lt;br /&gt;
&lt;br /&gt;
Now, whenever I do a new release build, I just run the batch file and I have a signed copy to use, and I did it without changing the project file to do it.&lt;img src="http://ryanfarley.com/blog/aggbug/38137.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2010/04/23/sign-a-.net-assembly-with-a-strong-name-without-recompiling.aspx</guid>
            <pubDate>Sat, 24 Apr 2010 06:46:27 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2010/04/23/sign-a-.net-assembly-with-a-strong-name-without-recompiling.aspx#feedback</comments>
            <slash:comments>10</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38137.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38137.aspx</trackback:ping>
        </item>
        <item>
            <title>ClickOnce Application "This operation is only supported on Windows 2000 SP3 or later" Error</title>
            <link>http://ryanfarley.com/blog/archive/2009/04/28/clickonce-application-this-operation-is-only-supported-on-windows-2000-sp3-or-later-error.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbff4be600000000b700000001000b00&lt;/div&gt;I have a ClickOnce app in production and a support case was opened where the ClickOnce installer was producing the following error:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-style: italic;"&gt;"This operation is only supported on Windows 2000 SP3 or later operating systems."&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
The weird thing is that the computer this error was happening on was Windows XP Professional SP2. So what gives? After a lot of heartache and tears :-p the solution eventually presented itself. The app was attempting to run in compatibility mode. In the case of my ClickOnce application, I had a WinForms app that was a launcher. It would spawn an IE process and navigate to the ClickOnce install URL. On this particular machine this WinForms app was set to run in Windows 2000 compatibility mode so it was launching the IE process in the same compatibility mode.&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="Compatibility Mode" src="http://files.farleyzone.com/images/CompatibilityMode.png" style="border: 1px solid black;" /&gt;&lt;br /&gt;
&lt;br /&gt;
I have no idea how the compatibility mode was set on the WinForms app. The user of this computer does not seem capable of knowing how to set this. However, once unchecking the compatibility mode all was well again. This would likely effect any .NET application, not just a ClickOnce application. But it caused me enough grief that I had to post the solution.&lt;img src="http://ryanfarley.com/blog/aggbug/38135.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2009/04/28/clickonce-application-this-operation-is-only-supported-on-windows-2000-sp3-or-later-error.aspx</guid>
            <pubDate>Wed, 29 Apr 2009 00:45:44 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2009/04/28/clickonce-application-this-operation-is-only-supported-on-windows-2000-sp3-or-later-error.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38135.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38135.aspx</trackback:ping>
        </item>
        <item>
            <title>Scraping, or Programatically Accessing, a Secure Webpage</title>
            <link>http://ryanfarley.com/blog/archive/2008/08/25/scraping-or-programatically-accessing-a-secure-webpage.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbff514a00000000b700000001000900&lt;/div&gt;There are many secure websites out there that provide useful information but do not have a public API to access it's data. A prime example of this is the LinkedIn website. You might love to gather some info from LinkedIn, but their promise to deliver a public API has yet to come to fruition. The problem is, the pages with all the good data are secure, requiring the user to log in before accessing these pages. Let's say we want to scrape this data from these pages programatically? We need to authenticate to access these pages. We can do that by reusing the authentication cookie from the site that we receive when we log in with a browser. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Note:&lt;/span&gt; I've mentioned LinkedIn as an example of a secure site to programatically access data from. It's actually a violation of LinkedIn's user agreement to scrape data from it's site. The techniques here apply to any form-based authenticated website, built on ASP.NET or anything else.&lt;/blockquote&gt; &lt;br /&gt;
Before we move on with this, I wanted to state a few assumptions with the approach I'll be showing here:&lt;br /&gt;
&lt;ol&gt;
    &lt;li&gt;You already have browser-based access to the secure pages (meaning you have a user account).&lt;/li&gt;
    &lt;li&gt;You're OK to use &lt;span style="font-style: italic;"&gt;your own&lt;/span&gt; authentication cookie to access the secure pages without violating some site agreement. Doing this sort of thing on a site that prohibits it can get you banned from the site. Remember, you'll be using something that can link these requests back to your own user account.&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
When you visit a webpage that requires some sort of form-based authentication, usually there is an authentication token stored in a cookie. This certainly is the case with any ASP.NET site using Forms Authentication and is the case with LinkedIn as well as about any other similar site out there. Even if it isn't a persistent cookie, and is only active for the session, there still is a cookie. This cookie is passed back to the website in the request header each time a page is accessed. We can sniff out the data for that cookie using &lt;a href="http://getfirebug.com/" target="_blank"&gt;Firebug&lt;/a&gt; (the awesomely-awesome Firefox addon), or using &lt;a href="http://www.fiddlertool.com/" target="_blank"&gt;Fiddler&lt;/a&gt; for IE.&lt;br /&gt;
&lt;br /&gt;
Using Firebug, we can access the secure page and take a look at the cookie value in the header. For my example, I'll be using a sample ASP.NET site using forms authentication, but this all works the same for non-ASP.NET sites too.&lt;br /&gt;
&lt;br /&gt;
&lt;img height="434" width="495" alt="" src="http://ryanfarley.com/images/ryanfarley_com/blog/FormsAuth_Cookie.jpg" /&gt;&lt;br /&gt;
&lt;br /&gt;
If you're using Fiddler, just access the page using IE and then you'll see the cookie data by going to the Headers section under the Session Inspector. &lt;br /&gt;
&lt;br /&gt;
For an ASP.NET site using forms authentication, the authentication token name is indicated in the "name" attribute of the forms key in the authentication section of the web.config. By default that name is ".ASPXAUTH", but you won't know what that name is, or the site might not even be an ASP.NET site. That is OK. You can usually pick out the authentication token in the cookie data, or just use the entire cookie.&lt;br /&gt;
&lt;br /&gt;
Now, using that cookie, we can use the following code to access the secure webpage:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; System.Net;&lt;br /&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; System.IO;&lt;br /&gt;&lt;span style="color: Green;"&gt;//...&lt;br /&gt;&lt;/span&gt; &lt;br /&gt; &lt;br /&gt;&lt;span style="color: Green;"&gt;//grab cookie authentication token from Firebug/Fiddler and add in here&lt;br /&gt;&lt;/span&gt;&lt;span style="color: Blue;"&gt;string&lt;/span&gt; cookiedata &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;".ASPXAUTH=FB8ADA49D4BFE4EF531A4539D0B74CCA6762F9CC6F62C8E..."&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;HttpWebRequest request &lt;span style="color: Navy;"&gt;=&lt;/span&gt; HttpWebRequest.Create(&lt;span style="color: rgb(0, 128, 128);"&gt;"http://somesite.com/securepage.aspx"&lt;/span&gt;) as HttpWebRequest;&lt;br /&gt;&lt;span style="color: Green;"&gt;//set the user agent so it looks like IE to not raise suspicion &lt;br /&gt;&lt;/span&gt;request.UserAgent &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"&lt;/span&gt;;&lt;br /&gt;request.Method &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"GET"&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: Green;"&gt;//set the cookie in the request header&lt;br /&gt;&lt;/span&gt;request.Headers.Add(&lt;span style="color: rgb(0, 128, 128);"&gt;"Cookie"&lt;/span&gt;, cookiedata);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;"&gt;//get the response from the server&lt;br /&gt;&lt;/span&gt;HttpWebResponse response &lt;span style="color: Navy;"&gt;=&lt;/span&gt; (HttpWebResponse)request.GetResponse();&lt;br /&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; (Stream stream &lt;span style="color: Navy;"&gt;=&lt;/span&gt; response.GetResponseStream())&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: Blue;"&gt;using&lt;/span&gt; (StreamReader reader &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;new&lt;/span&gt; StreamReader(stream))&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;"&gt;string&lt;/span&gt; pagedata &lt;span style="color: Navy;"&gt;=&lt;/span&gt; reader.ReadToEnd();&lt;br /&gt;        &lt;span style="color: Green;"&gt;//now we can scrape the contents of the secure page as needed&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: Green;"&gt;//since the page contents is now stored in our pagedata string&lt;br /&gt;&lt;/span&gt;    }&lt;br /&gt;}&lt;br /&gt;response.Close();&lt;/pre&gt;
&lt;br /&gt;
One thing to point out here, since we're passing the entire contents of the cookie, I'm just adding that as a whole to the request header instead of adding each cookie element to the request.Cookie container. &lt;br /&gt;
&lt;br /&gt;
If I wire that up in a form, we'll quickly see the secure page since the site will see the authentication token in the cookie sent in the page header and will not redirect us to the login page.&lt;br /&gt;
&lt;br /&gt;
&lt;img height="212" width="515" src="http://ryanfarley.com/images/ryanfarley_com/blog/FormsAuth_ReqPage.jpg" alt="" /&gt;&lt;br /&gt;
&lt;br /&gt;
Not bad. We can now scrape any data we'd like from the secure page contents. Just to point out, we're not just limited to reading the data. We can also send form data back to the site as a POST on secure pages as well.&lt;img src="http://ryanfarley.com/blog/aggbug/38133.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2008/08/25/scraping-or-programatically-accessing-a-secure-webpage.aspx</guid>
            <pubDate>Tue, 26 Aug 2008 06:07:01 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2008/08/25/scraping-or-programatically-accessing-a-secure-webpage.aspx#feedback</comments>
            <slash:comments>34</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38133.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38133.aspx</trackback:ping>
        </item>
        <item>
            <title>More on Device Filtering With ASP.NET Server Control Properties</title>
            <link>http://ryanfarley.com/blog/archive/2008/08/14/more-on-device-filtering-with-asp.net-server-control-properties.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbffd52a000000000bf4000001000100&lt;/div&gt;&lt;a href="http://ryanfarley.com/blog/archive/2008/08/14/set-browser-specific-asp.net-server-control-properties-and-taking-an.aspx"&gt;I posted yesterday&lt;/a&gt; about setting ASP.NET Browser control properties differently for different browsers by using device filtering syntax for setting the properties. I've received some questions via e-mail about that post so I wanted to follow up on some additional things I've found on this topic.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="link"&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;See this first:&lt;/span&gt; &lt;a href="http://ryanfarley.com/blog/archive/2008/08/14/set-browser-specific-asp.net-server-control-properties-and-taking-an.aspx"&gt;Set Browser Specific ASP.NET Server Control Properties and Taking an ASP.NET Site Offline&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;1) This can only be done declaratively&lt;/span&gt;. If you need to do this in the code-behind you'll need to use Request.Browser. Example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: Blue;"&gt;switch&lt;/span&gt; (Request.Browser.Browser.ToLower())&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: Blue;"&gt;case&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"ie"&lt;/span&gt;:&lt;br /&gt;        &lt;span style="color: Blue;"&gt;if&lt;/span&gt; (Request.Browser.MajorVersion == 7)&lt;br /&gt;            labelText.Text &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Hello IE7!"&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;else&lt;/span&gt; &lt;br /&gt;            labelText.Text &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Hello IE (time to upgrade!)"&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;break&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: Blue;"&gt;case&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"firefox"&lt;/span&gt;:&lt;br /&gt;        labelText.Text &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Hello Firefox"&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;break&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: Blue;"&gt;default&lt;/span&gt;:&lt;br /&gt;        labelText.Text &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Hello other browser"&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;break&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;2) There is no designer support.&lt;/span&gt; Don't expect to see this stuff in the intellisense. It won't be there, but it will work.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;3) Not just for simple properties.&lt;/span&gt; This device filtering technique worked with every property I tried it with. In fact, it even worked in other unexpected ways as well, such as with templated controls. Take a look at the following example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;lt;asp:Menu runat=&lt;span style="color: rgb(0, 128, 128);"&gt;"server"&lt;/span&gt; id=&lt;span style="color: rgb(0, 128, 128);"&gt;"myMenu"&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;ie:Items&amp;gt;&lt;br /&gt;       &amp;lt;asp:MenuItem Text=&lt;span style="color: rgb(0, 128, 128);"&gt;"IE Item"&lt;/span&gt; &lt;span style="color: Navy;"&gt;/&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/ie:Items&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;mozilla:Items&amp;gt;&lt;br /&gt;       &amp;lt;asp:MenuItem Text=&lt;span style="color: rgb(0, 128, 128);"&gt;"Firefox Item"&lt;/span&gt; &lt;span style="color: Navy;"&gt;/&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/mozilla:Items&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;Items&amp;gt;&lt;br /&gt;        &amp;lt;asp:MenuItem Text=&lt;span style="color: rgb(0, 128, 128);"&gt;"Other Item"&lt;/span&gt; &lt;span style="color: Navy;"&gt;/&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/Items&amp;gt;&lt;br /&gt;&amp;lt;/asp:Menu&amp;gt;&lt;/pre&gt;
&lt;br /&gt;
Now that is pretty cool.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;4) How it works.&lt;/span&gt; This didn't take too long to work out. A little bit of digging quickly showed how this all comes together because it works just how you would probably guess. The biggest question is "&lt;span style="font-style: italic; font-weight: bold;"&gt;how do you know what device values you can use for filtering?&lt;/span&gt;". In the .NET Framework directory you'll find some config files showing how to behave and render controls for different types of browsers. &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers&lt;/pre&gt;
&lt;br /&gt;
In that folder you'll see several config files named things like "ie.browser", "mozilla.browser", "safari.browser", "palm.browser", etc. In each of these files there are several "browser" elements, each with an ID. These ID values are what can be used to declaratively filter server control properties for the specific devices. Mind you, it's not just the names of the files, but the browser ID values contained inside. This means that you can get &lt;span style="font-style: italic;"&gt;very&lt;/span&gt; specific about the targeted browser for a property value. Instead of just specifying "ie", you could use any of the following "ie", "ie5", "ie5to9", "ieaol", "ie4" and many many more. Also, you can edit these, or add an App_Browsers folder to your propject and place a new file named "something.browser" in it to define your specific browser capabilities.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;5) It works with directives too!&lt;/span&gt; This was the one that blew me away. You can use it on directives as well! That means, control directives (to modify properties, attributes, templates, etc), page directives (to modify CodePage, MasterPageFile, Culture, Theme, etc), and master page directives (to modify CodeFile, Viewstate, etc). &lt;span style="font-style: italic;"&gt;W-w-what?&lt;/span&gt; The following will set a separate master page for IE and Firefox and a third for all other browsers:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;lt;%@ Page Language=&lt;span style="color: rgb(0, 128, 128);"&gt;"C#"&lt;/span&gt; &lt;br /&gt;    ie:MasterPageFile=&lt;span style="color: rgb(0, 128, 128);"&gt;"~/MasterPageIE.master"&lt;/span&gt; &lt;br /&gt;    mozilla:MasterPageFile=&lt;span style="color: rgb(0, 128, 128);"&gt;"~/MasterPageFirefox.master"&lt;/span&gt; &lt;br /&gt;    MasterPageFile=&lt;span style="color: rgb(0, 128, 128);"&gt;"~/MasterPageGeneric.master"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: Navy;"&gt;%&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;br /&gt;
Freaky, I know.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;6) Why use this?&lt;/span&gt; There are a lot of uses for device filtering with server control properties. Consider this. You have a simple page with a welcome label. It's a simple page so you don't really need a separate mobile version of the page. You could shorten that text easily for anyone on a PocketPC IE or Palm browser to account for the limited screen real estate. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;7) You can disallow the use of device filtering in your custom controls if you want.&lt;/span&gt; If you build your own control and you &lt;span style="font-style: italic;"&gt;don't&lt;/span&gt; want the consuming developer to be able to use device filtering with it's properties, you can mark the class with the &lt;span style="font-family: Courier New;"&gt;Filterable(false)&lt;/span&gt; attribute and it will ignore the device specific properties that are set for the control.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Well, that is about all I know. I'm still just trying to cope with the fact that this has been there since ASP.NET 2.0 and I am just finding out about it now. Apparently, I'm not the only one since it was difficult to track down details on this.&lt;img src="http://ryanfarley.com/blog/aggbug/38131.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2008/08/14/more-on-device-filtering-with-asp.net-server-control-properties.aspx</guid>
            <pubDate>Thu, 14 Aug 2008 19:13:57 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2008/08/14/more-on-device-filtering-with-asp.net-server-control-properties.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38131.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38131.aspx</trackback:ping>
        </item>
        <item>
            <title>Set Browser Specific ASP.NET Server Control Properties and Taking an ASP.NET Site Offline</title>
            <link>http://ryanfarley.com/blog/archive/2008/08/14/set-browser-specific-asp.net-server-control-properties-and-taking-an.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbffc72a0000000009f4000001000100&lt;/div&gt;Isn't it great when you work with a tool day after day and you thought you knew everything there was to know about it? Then find out something that has been there for a long time that you somehow missed? Here's two things that have been in ASP.NET since version 2.0 that I somehow missed until just recently.&lt;br /&gt;
&lt;br /&gt;
...as if there are only 2? Hehe. I am sure there are many more, but I was actually surprised when I came across these items. They're simple enough that I could not believe that I missed them before. I'm sure that I'm not the only one who missed these items. The fact that I hadn't heard about them indicates that they've not been blogged about heavily or that obvious in the docs (if at all?).&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3" style="font-weight: bold;"&gt;Setting Server Control Properties Based on Target Browser&lt;/font&gt;&lt;br /&gt;
This one was surprising. I came across this one on &lt;a href="http://weblogs.asp.net/johnkatsiotis/archive/2008/08/12/asp-net-browsers-filter.aspx" target="_blank"&gt;John Katsiotis' Web Dev &amp;amp; Stuff&lt;/a&gt;. The fact that I've written code so many times to accomplish this, when it's apparently been built in since version 2.0 just kills me. The properties of server controls will let you specify a browser filter to apply the property value for. That is, you can set a different value for a property for IE than for Firefox - and for anything else. I didn't try all properties, but I did try many that would matter, such as Text and OnClientClick etc, and they do work. Take a look at the following markup:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;lt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp:Label&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; runat=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"server"&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; ID=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"labelText"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    ie:Text=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"This is IE text"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    mozilla:Text=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"This is Firefox text"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    Text=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"This is general text"&lt;/span&gt; &lt;br /&gt;/&amp;gt;  &lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;span style="color: rgb(128, 0, 0);"&gt;br&lt;/span&gt; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp:Button&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; runat=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"server"&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; ID=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"buttonText"&lt;/span&gt; &lt;br /&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;   ie:Text=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"IE Button"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    ie:OnClientClick=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"javascript:alert('Hello IE!');"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    mozilla:Text=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"FF Button"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    mozilla:OnClientClick=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"javascript:alert('Hello Firefox!');"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    Text=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"General Button"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    OnClientClick=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;"javascript:alert('Hello everyone else!');"&lt;/span&gt; &lt;br /&gt;/&amp;gt;&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
Notice the "ie:" and "mozilla:" prefixes on the Text and OnClientClick properties. The results? Take a look. The following was the result in Firefox:&lt;br /&gt;
&lt;br /&gt;
&lt;img height="282" width="530" alt="" src="/images/ryanfarley_com/blog/BrowserProperties-FF.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
In Internet Explorer:&lt;br /&gt;
&lt;br /&gt;
&lt;img height="282" width="530" alt="" src="/images/ryanfarley_com/blog/BrowserProperties-IE.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
In Opera (or anything other than IE or Firefox since I've defined properties for those)&lt;br /&gt;
&lt;br /&gt;
&lt;img height="282" width="530" alt="" src="/images/ryanfarley_com/blog/BrowserProperties-General.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
Wow. Pretty cool. Now, I am not saying that this will apply in all cases. It doesn't seem to differentiate between IE7 and IE6, so there are some big limitations. However, this is quite a cool trick and one that will without question come in handy.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; I posted a follow up that shows a lot more of the capabilities of using these device filters to target specific browsers in ASP.NET.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="link"&gt;See &lt;a href="http://ryanfarley.com/blog/archive/2008/08/14/more-on-device-filtering-with-asp.net-server-control-properties.aspx"&gt;More on Device Filtering With ASP.NET Server Control Properties&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;Taking an ASP.NET Site Offline with a Message&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
This was another one that I was literally beside myself that I didn't know this one before. A fellow business partner of mine named James Sutton mentioned this one to me. This one's been around since ASP.NET 2.0 as well. If you have an ASP.NET web application site, and you place a text file named "app_offline.htm" in the root of the site, &lt;span style="font-weight: bold; font-style: italic;"&gt;all requests to that website will redirect to that app_offline.htm file&lt;/span&gt;. Basically, if you need to take an entire ASP.NET site offline, you can place some nice message in that file. Then, any new requests to a URL, any URL, in that website will redirect to that file allowing you to do maintenance to the site, upgrades, or whatever. It is not really a redirect though. ASP.NET essentially shuts down the site, unloads it from the server, and stops processing any requests to that site. That is, until you delete the app_offline.htm file - then things will continue as normal and your ASP.NET site will load up and start serving requests again.  &lt;br /&gt;
&lt;br /&gt;
A super-cool side effect of this is that any files that are locked by the site, such as a database or other resources, are freed since the application domain has been unloaded from the server. This allows you to remove the locks from those files and replace them, without the need to do a full IISRESET, taking down other sites on the server. One thing to keep in mind with this file however, make sure you out enough content in it so it is larger than 512 bytes or IE will consider it a 404 and will display the 404 instead of the contents of your app_offline.htm file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I love coming across new tricks like this, but it does make me wonder, why didn't I know about these before?&lt;img src="http://ryanfarley.com/blog/aggbug/38130.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2008/08/14/set-browser-specific-asp.net-server-control-properties-and-taking-an.aspx</guid>
            <pubDate>Thu, 14 Aug 2008 07:00:18 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2008/08/14/set-browser-specific-asp.net-server-control-properties-and-taking-an.aspx#feedback</comments>
            <slash:comments>13</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38130.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38130.aspx</trackback:ping>
        </item>
        <item>
            <title>Adding Calendar Items to Outlook or Other Calendar App from a Webpage via iCalendar</title>
            <link>http://ryanfarley.com/blog/archive/2008/08/08/adding-calendar-items-from-a-webpage-via-icalendar.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbff300c00000000b700000001000700&lt;/div&gt;If you have a website that maintains a list of events for users, it is a great idea to allow users to selectively add those events to their own calendar. Using automation from a website with something like Outlook is a bad idea. It would be blocked by the browser's security and your users might use something else for their calendar. Fortunately, many main-stream (most?) calendar applications, such as Outlook, Windows Calendar on Vista, and a whole lot more, support the iCalendar specification. This makes adding items from your applications a breeze.&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;The iCalendar Specification&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
The iCalendar spec (see &lt;a target="_blank" href="http://tools.ietf.org/html/rfc2445"&gt;RFC 2445&lt;/a&gt;) was created to extend an earlier created vCalendar spec. This spec basically provides a universally accepted way to represent a calendar item in a file, or really, as text. An iCalendar can represent some single generic calendar item, or an Event, To-Do, Journal item, and can even include free/busy schedule information. We are going to focus here on including only a single event in our iCalendar data, although it can also represent multiple items all within the same iCalendar. When expressed as a file, the iCalendar data will typically have an "ics" extension, but really it is just text. It also has a MIME type of "text/calendar"&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;Scenario&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
For our scenario, we'll assume we have a website with events on it. For any of these events, we want to allow the user to be able to selectively add an event to their own local calendar. On the display of an event on our website, we'll provide a link that the user can click to add the event to their calendar. Here's a sample of a website that I've used this on to give you an idea:&lt;br /&gt;
&lt;br /&gt;
&lt;img height="303" width="439" src="/images/ryanfarley_com/blog/CalendarSample.jpg" alt="" /&gt;&lt;br /&gt;
&lt;br /&gt;
The user clicks that link and we get some &lt;a href="http://www.hanselman.com/blog/ILikeCakeCakemailNinjasOnFireAndOtherAnecdotes.aspx" target="_blank"&gt;jazz hands&lt;/a&gt; and it is added to the user's calendar. Let's take a look at how it all works.&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;The iCalendar Class&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
As I mentioned before, the iCalendar data is just text. The thing about it is, it is &lt;span style="font-weight: bold;"&gt;ugly&lt;/span&gt; text. I don't like ugly text. I want to write it once and then forget it ever existed. So, I created a class that does all the ugly text for me to use whenever I need. If you're really wanting to see more of this ugly text then you and the rest of your zombie friends can go nicely over to the RFC and read all you want.&lt;br /&gt;
&lt;br /&gt;
Here's my class:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; System.Text;&lt;br /&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;"&gt;namespace&lt;/span&gt; RF.Events&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: Blue;"&gt;public&lt;/span&gt; enum PriorityLevel : &lt;span style="color: Blue;"&gt;int&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        Normal &lt;span style="color: Navy;"&gt;=&lt;/span&gt; 5,&lt;br /&gt;        High &lt;span style="color: Navy;"&gt;=&lt;/span&gt; 1,&lt;br /&gt;        Low &lt;span style="color: Navy;"&gt;=&lt;/span&gt; 9&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;class&lt;/span&gt; Event&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;"&gt;const&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt; _DATEFORMAT &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"yyyyMMdd\\THHmmss\\Z"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; Event() { }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; DateTime StartTime;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; DateTime EndTime;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt; Location &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt; Title &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt; Description &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;bool&lt;/span&gt; UseAlarm &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; PriorityLevel Priority &lt;span style="color: Navy;"&gt;=&lt;/span&gt; PriorityLevel.Normal;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt; Category &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;override&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt; ToString()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;"&gt;return&lt;/span&gt; Output;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt; Output&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;"&gt;get&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                StringBuilder sb &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt;&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"BEGIN:VEVENT\n\n"&lt;/span&gt;);&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"DTSTART:"&lt;/span&gt;);&lt;br /&gt;                sb.Append(StartTime.ToUniversalTime().ToString(_DATEFORMAT));&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"\nDTEND:"&lt;/span&gt;);&lt;br /&gt;                sb.Append(EndTime.ToUniversalTime().ToString(_DATEFORMAT));&lt;br /&gt;&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"\nLOCATION:"&lt;/span&gt;);&lt;br /&gt;                sb.Append(Location);&lt;br /&gt;&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"\nCATEGORIES:"&lt;/span&gt;);&lt;br /&gt;                sb.Append(Category);&lt;br /&gt;&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"\nTRANSP:OPAQUE\n"&lt;/span&gt;);&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"SEQUENCE:0\n"&lt;/span&gt;);&lt;br /&gt;                sb.AppendFormat(&lt;span style="color: rgb(0, 128, 128);"&gt;"UID:RFCALITEM{0}\n"&lt;/span&gt;, DateTime.Now.Ticks);&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"DTSTAMP:"&lt;/span&gt;);&lt;br /&gt;                sb.Append(StartTime.ToUniversalTime().ToString(_DATEFORMAT));&lt;br /&gt;&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"\nDESCRIPTION:"&lt;/span&gt;);&lt;br /&gt;                sb.Append(Description);&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"\nSUMMARY:"&lt;/span&gt;);&lt;br /&gt;                sb.Append(Title);&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"\n\nPRIORITY:"&lt;/span&gt;);&lt;br /&gt;                sb.Append((&lt;span style="color: Blue;"&gt;int&lt;/span&gt;)Priority);&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"\nCLASS:PUBLIC\n"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: Blue;"&gt;if&lt;/span&gt; (UseAlarm)&lt;br /&gt;                {&lt;br /&gt;                    sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"BEGIN:VALARM\n"&lt;/span&gt;);&lt;br /&gt;                    sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"TRIGGER:PT15M\n"&lt;/span&gt;);&lt;br /&gt;                    sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"ACTION:DISPLAY\n"&lt;/span&gt;);&lt;br /&gt;                    sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"DESCRIPTION:Reminder\n"&lt;/span&gt;);&lt;br /&gt;                    sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"PRIORITY:5\n"&lt;/span&gt;);&lt;br /&gt;                    sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"END:VALARM\n"&lt;/span&gt;);&lt;br /&gt;                }&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"END:VEVENT\n"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: Blue;"&gt;return&lt;/span&gt; sb.ToString();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;class&lt;/span&gt; iCalendar&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; iCalendar()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;"&gt;this&lt;/span&gt;.Events &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;new&lt;/span&gt; List&amp;lt;Event&amp;gt;();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; List&amp;lt;Event&amp;gt; Events;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;override&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt; ToString()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;"&gt;this&lt;/span&gt;.Output;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;string&lt;/span&gt; Output&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: Blue;"&gt;get&lt;/span&gt; &lt;br /&gt;            { &lt;br /&gt;                StringBuilder sb &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt;&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"BEGIN:VCALENDAR\n"&lt;/span&gt;);&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"PRODID:-//RyanFarley.com//iCalendar Sample MIMEDIR//EN\n"&lt;/span&gt;);&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"VERSION:2.0\n"&lt;/span&gt;);&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"METHOD:PUBLISH\n"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: Blue;"&gt;foreach&lt;/span&gt; (Event ev &lt;span style="color: Blue;"&gt;in&lt;/span&gt; Events)&lt;br /&gt;                    sb.Append(ev.Output);&lt;br /&gt;&lt;br /&gt;                sb.Append(&lt;span style="color: rgb(0, 128, 128);"&gt;"END:VCALENDAR"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: Blue;"&gt;return&lt;/span&gt; sb.ToString();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;
So, first question. Why the separation of the Event item from the rest of the iCalendar item? We'll get to that. For now, here's how we'll use that class. Let's add it to a handler to send back the iCalendar data in the response. We'll call this handler from the link we provide to the user (Typically we would do something like pass an "event ID" of some kind to it and grab the associated data from a database or something. We'll ignore all that stuff in this example to keep it simple).&lt;br /&gt;
&lt;br /&gt;
Here's our handler code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;lt;%@ WebHandler Language=&lt;span style="color: rgb(0, 128, 128);"&gt;"C#"&lt;/span&gt; Class=&lt;span style="color: rgb(0, 128, 128);"&gt;"CalendarItem"&lt;/span&gt; &lt;span style="color: Navy;"&gt;%&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; System.Web;&lt;br /&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; System.Text;&lt;br /&gt;&lt;span style="color: Blue;"&gt;using&lt;/span&gt; RF.Events;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;class&lt;/span&gt; CalendarItem : IHttpHandler &lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;void&lt;/span&gt; ProcessRequest(HttpContext context) &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Green;"&gt;// Set up the Event item first. This would typically come &lt;br /&gt;&lt;/span&gt;        &lt;span style="color: Green;"&gt;// from a database or some object in the application&lt;br /&gt;&lt;/span&gt;        Event ev &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;new&lt;/span&gt; Event();&lt;br /&gt;        ev.Title &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Some Event"&lt;/span&gt;;&lt;br /&gt;        ev.Description &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"This is a test event. Yeye.\\nKTHXBYE"&lt;/span&gt;;&lt;br /&gt;        ev.Location &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"At ryanfarley.com"&lt;/span&gt;;&lt;br /&gt;        ev.UseAlarm &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;        ev.StartTime &lt;span style="color: Navy;"&gt;=&lt;/span&gt; DateTime.Parse(&lt;span style="color: rgb(0, 128, 128);"&gt;"11/1/2008 8:00:00 AM"&lt;/span&gt;);&lt;br /&gt;        ev.EndTime &lt;span style="color: Navy;"&gt;=&lt;/span&gt; DateTime.Parse(&lt;span style="color: rgb(0, 128, 128);"&gt;"11/1/2008 10:00:00 AM"&lt;/span&gt;);&lt;br /&gt;        ev.Priority &lt;span style="color: Navy;"&gt;=&lt;/span&gt; PriorityLevel.Normal;&lt;br /&gt;        ev.Category &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Test Category"&lt;/span&gt;;&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: Green;"&gt;// Now add the event to an iCalendar&lt;br /&gt;&lt;/span&gt;        iCalendar ical &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;new&lt;/span&gt; iCalendar();&lt;br /&gt;        ical.Events.Add(ev);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Green;"&gt;// Set the content-type of the response and file name&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: Green;"&gt;// so Windows knows how to handle the response.&lt;br /&gt;&lt;/span&gt;        context.Response.ContentType &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"text/calendar"&lt;/span&gt;;&lt;br /&gt;        context.Response.AddHeader(&lt;span style="color: rgb(0, 128, 128);"&gt;"content-disposition"&lt;/span&gt;, &lt;span style="color: rgb(0, 128, 128);"&gt;"inline;filename=CalendarEvent.ics"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Green;"&gt;// Write the bytes of the iCalendar item output to the resonse stream&lt;br /&gt;&lt;/span&gt;        context.Response.BinaryWrite(&lt;span style="color: Blue;"&gt;new&lt;/span&gt; System.Text.ASCIIEncoding().GetBytes(ical.Output));&lt;br /&gt;        context.Response.End();&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    &lt;span style="color: Blue;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;"&gt;bool&lt;/span&gt; IsReusable &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: Blue;"&gt;get&lt;/span&gt; { &lt;span style="color: Blue;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;"&gt;false&lt;/span&gt;; }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;
If we add that as a hyperlink on a webpage, like this:&lt;br /&gt;
&lt;br /&gt;
&lt;img height="164" width="302" src="/images/ryanfarley_com/blog/CalendarSample2.jpg" alt="" /&gt;&lt;br /&gt;
&lt;br /&gt;
The user can click it (this is where we get the jazz hands) and they are prompted with this:&lt;br /&gt;
&lt;br /&gt;
&lt;img height="326" width="425" src="/images/ryanfarley_com/blog/CalendarSample3.jpg" alt="" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Of course, here they click OK and they are presented with some sort of dialog from whatever app is associated with ics files. On my machine that is Outlook, so I get this:&lt;br /&gt;
&lt;br /&gt;
&lt;img height="433" width="576" src="/images/ryanfarley_com/blog/CalendarSample4.jpg" alt="" /&gt;&lt;br /&gt;
&lt;br /&gt;
Cool. The user clicks the Save &amp;amp; Close and it now appears on their calendar. We're not just limited to do this from a webpage either. We could just as easily save the &lt;span style="font-family: Courier New;"&gt;iCalendar.Output&lt;/span&gt; to a file and Process.Start it to open it for the user if we're in a Windows app. Or attach it to an e-mail to a user, similar to services like WebEx, GotoMeeting, and other services that send you an e-mail with an iCalendar file attached.&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;Adding Multiple Events to Create an iCalendar Feed&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
Now, back to that separation of the Event from the iCalendar class. Why is that? The iCalendar spec indicates that an iCalendar can have one, or multiple events in it. If you've ever added an iCalendar feed to Outlook from your Google Calendar or TripIt, etc, this feed is not an RSS feed or something like that. It is a big long iCalendar file containing multiple events in it. We can create the same with the following code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;        &lt;span style="color: Green;"&gt;// Create the iCalendar&lt;br /&gt;&lt;/span&gt;        iCalendar ical &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;new&lt;/span&gt; iCalendar();&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: Green;"&gt;// Add the first event and add it to the iCalendar&lt;br /&gt;&lt;/span&gt;        Event ev &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;new&lt;/span&gt; Event();&lt;br /&gt;        ev.Title &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Some Event #1"&lt;/span&gt;;&lt;br /&gt;        ev.Description &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"This is a test event #1. Yeye.\\nKTHXBYE"&lt;/span&gt;;&lt;br /&gt;        ev.Location &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"At ryanfarley.com"&lt;/span&gt;;&lt;br /&gt;        ev.UseAlarm &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;        ev.StartTime &lt;span style="color: Navy;"&gt;=&lt;/span&gt; DateTime.Parse(&lt;span style="color: rgb(0, 128, 128);"&gt;"11/1/2008 8:00:00 AM"&lt;/span&gt;);&lt;br /&gt;        ev.EndTime &lt;span style="color: Navy;"&gt;=&lt;/span&gt; DateTime.Parse(&lt;span style="color: rgb(0, 128, 128);"&gt;"11/1/2008 10:00:00 AM"&lt;/span&gt;);&lt;br /&gt;        ev.Priority &lt;span style="color: Navy;"&gt;=&lt;/span&gt; PriorityLevel.Normal;&lt;br /&gt;        ev.Category &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Test Category"&lt;/span&gt;;        &lt;br /&gt;        ical.Events.Add(ev);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Green;"&gt;// Add the second event and add it to the iCalendar&lt;br /&gt;&lt;/span&gt;        ev &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;new&lt;/span&gt; Event();&lt;br /&gt;        ev.Title &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Some Event #2"&lt;/span&gt;;&lt;br /&gt;        ev.Description &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"This is a test event #2. Yeye.\\nKTHXBYE"&lt;/span&gt;;&lt;br /&gt;        ev.Location &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"At ryanfarley.com"&lt;/span&gt;;&lt;br /&gt;        ev.UseAlarm &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;        ev.StartTime &lt;span style="color: Navy;"&gt;=&lt;/span&gt; DateTime.Parse(&lt;span style="color: rgb(0, 128, 128);"&gt;"11/5/2008 8:00:00 AM"&lt;/span&gt;);&lt;br /&gt;        ev.EndTime &lt;span style="color: Navy;"&gt;=&lt;/span&gt; DateTime.Parse(&lt;span style="color: rgb(0, 128, 128);"&gt;"11/5/2008 10:00:00 AM"&lt;/span&gt;);&lt;br /&gt;        ev.Priority &lt;span style="color: Navy;"&gt;=&lt;/span&gt; PriorityLevel.High;&lt;br /&gt;        ev.Category &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"Test Category"&lt;/span&gt;;&lt;br /&gt;        ical.Events.Add(ev);&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color: Green;"&gt;// ...you get the idea&lt;br /&gt;&lt;/span&gt;        &lt;br /&gt;        &lt;span style="color: Green;"&gt;// Now out iCalendar contains multiple events.&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: Green;"&gt;// We can output it all to the response stream.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: Green;"&gt;// Set the content-type of the response and file name&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: Green;"&gt;// so Windows knows how to handle the response.&lt;br /&gt;&lt;/span&gt;        context.Response.ContentType &lt;span style="color: Navy;"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 128, 128);"&gt;"text/calendar"&lt;/span&gt;;&lt;br /&gt;        context.Response.AddHeader(&lt;span style="color: rgb(0, 128, 128);"&gt;"content-disposition"&lt;/span&gt;, &lt;span style="color: rgb(0, 128, 128);"&gt;"inline;filename=CalendarEvent.ics"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Green;"&gt;// Write the bytes of the iCalendar item output to the resonse stream&lt;br /&gt;&lt;/span&gt;        context.Response.BinaryWrite(&lt;span style="color: Blue;"&gt;new&lt;/span&gt; System.Text.ASCIIEncoding().GetBytes(ical.Output));&lt;br /&gt;        context.Response.End();&lt;/pre&gt;
&lt;br /&gt;
What happens now when the user clicks our link? They'll get prompted just as before, but when they click OK to add it, it will add the iCalendar feed as a second calendar in their calendar application. In Outlook it will show as a separate calendar which I can view side-by-side with my existing one or overlay on top of my existing one. In this case we'd also want to include the appropriate 304 response status in case the calendar item hasn't changed so we keep things nice.&lt;br /&gt;
&lt;br /&gt;
So that is it. Not bad work and we've got a reusable class we can use for single item, or complete calendar feeds. Have fun.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="link"&gt;&lt;a target="_blank" href="http://files.farleyzone.com/downloads/code/iCalendar.cs.txt"&gt;Download the iCalendar class&lt;/a&gt;&lt;/div&gt;&lt;img src="http://ryanfarley.com/blog/aggbug/38129.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2008/08/08/adding-calendar-items-from-a-webpage-via-icalendar.aspx</guid>
            <pubDate>Fri, 08 Aug 2008 07:42:43 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2008/08/08/adding-calendar-items-from-a-webpage-via-icalendar.aspx#feedback</comments>
            <slash:comments>23</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38129.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38129.aspx</trackback:ping>
        </item>
        <item>
            <title>Must Have .NET Developer Podcasts</title>
            <link>http://ryanfarley.com/blog/archive/2008/07/30/must-have-.net-developer-podcasts.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbffa00b00000000b700000001000300&lt;/div&gt;&lt;div&gt;&lt;img height="97" align="left" width="129" src="http://ryanfarley.com/images/ryanfarley_com/blog/Podcasts-Zune-small.jpg" style="margin-right: 6px;" alt="" /&gt;&lt;a href="http://ryanfarley.com/blog/archive/2008/07/30/becoming-a-better-developer.aspx"&gt;In my last post&lt;/a&gt; I mentioned some of the podcasts that I've been listening to that have inspired me as a .NET developer. I thought it would be a good idea to start a list of all the podcasts that have taken over my Zune lately and some that I am planning on checking out.&lt;/div&gt;
&lt;br clear="all" /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;font size="2"&gt;&lt;span style="font-weight: bold;"&gt;&lt;font size="3"&gt;My Current Favorites&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-weight: bold;" class="link"&gt;&lt;a href="http://herdingcode.com/" target="_blank"&gt;HerdingCode&lt;/a&gt;&lt;/div&gt;
HerdingCode is just a great discussion between &lt;a target="_blank" href="http://weblogs.asp.net/jgalloway"&gt;Jon Gallaway&lt;/a&gt;, &lt;a target="_blank" href="http://odetocode.com/"&gt;K. Scott Allen&lt;/a&gt;, &lt;a target="_blank" href="http://weblogs.asp.net/kdente"&gt;Kevin Dente&lt;/a&gt;, and &lt;a target="_blank" href="http://lazycoder.com/"&gt;Scott Koon&lt;/a&gt; on .NET development topics. I suppose the thing that I really like about it is that it's just down to earth, like you're just listening in on a conversation that they would be having anyway.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-weight: bold;" class="link"&gt;&lt;a href="http://hanselminutes.com/" target="_blank"&gt;Hanselminutes&lt;/a&gt;&lt;/div&gt;
There's likely few that don't know who &lt;a href="http://hanselman.com/" target="_blank"&gt;Scott Hanselman&lt;/a&gt; is. He manages to carry the same passion and energy he shows on his blog to the Hanselminutes show. His co-host is Carl Franklin (see DotNetRocks below) who is always equally as great.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-weight: bold;" class="link"&gt;&lt;a href="http://dotnetrocks.com/" target="_blank"&gt;DotNetRocks&lt;/a&gt;&lt;/div&gt;
DotNetRocks, from &lt;a target="_blank" href="http://www.intellectualhedonism.com/"&gt;Carl Franklin&lt;/a&gt;, has been around for a long time. Carl keeps interesting topics on the show that range from development related, to technology. The show isn't supposed to be a show &lt;span style="font-style: italic;"&gt;about&lt;/span&gt; .NET, but is a show &lt;span style="font-style: italic;"&gt;for&lt;/span&gt; .NET developers. Carl's co-host is &lt;a href="http://www.campbellassociates.ca/blog/" target="_blank"&gt;Richard Campbell&lt;/a&gt;, who always seems to know what he is talking about. &lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-weight: bold;" class="link"&gt;&lt;a href="http://deepfriedbytes.com/" target="_blank"&gt;Deep Fried Bytes&lt;/a&gt;&lt;/div&gt;
Deep Fried Bytes is a show from &lt;a href="http://keithelder.net/blog/" target="_blank"&gt;Keith Elder&lt;/a&gt; and &lt;a href="http://blog.cloudsocket.com/" target="_blank"&gt;Chris "Woody" Woodruff&lt;/a&gt;. This is more of a technology show, but with a strong slant for .NET developers. Very laid back and they've had some great guests.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-weight: bold;" class="link"&gt;&lt;a href="http://altnetpodcast.com/" target="_blank"&gt;ALT.NET Podcast&lt;/a&gt;&lt;/div&gt;
The Alt.NET podcast is a podcast from the &lt;a target="_blank" href="http://altdotnet.org/"&gt;ALT.NET&lt;/a&gt; movement that focuses on improving ourselves as developers, challenging assumptions, and looks at things available to help us in our pursuit of excellence as software developers. This is one I've just added to my list, so I'm still pretty much getting started with it. So far it's been great (but it is a bit less casual than some of the others I've listed).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;Others I Plan on Checking Out&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-weight: bold;" class="link"&gt;&lt;a target="_blank" href="http://polymorphicpodcast.com/"&gt;PolymorphicPodcast&lt;/a&gt;&lt;/div&gt;
&lt;div style="font-weight: bold;" class="link"&gt;&lt;a target="_blank" href="http://aspnetpodcast.com/"&gt;ASP.NET Podcast&lt;/a&gt;&lt;/div&gt;
&lt;div style="font-weight: bold;" class="link"&gt;&lt;a target="_blank" href="http://blog.stackoverflow.com/category/podcasts/"&gt;StackOverflow&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Are there any other great ones I'm missing from the list?&lt;img src="http://ryanfarley.com/blog/aggbug/38127.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2008/07/30/must-have-.net-developer-podcasts.aspx</guid>
            <pubDate>Wed, 30 Jul 2008 21:56:16 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2008/07/30/must-have-.net-developer-podcasts.aspx#feedback</comments>
            <slash:comments>17</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38127.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38127.aspx</trackback:ping>
        </item>
        <item>
            <title>Becoming a Better Developer</title>
            <link>http://ryanfarley.com/blog/archive/2008/07/30/becoming-a-better-developer.aspx</link>
            <description>&lt;div style="display:none"&gt;qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbff990b00000000b100000001000500&lt;/div&gt;&lt;a href="http://ryanfarley.com/blog/archive/2008/07/25/the-relaunch-of-ryanfarley.com-and-how-twitter-helped-my-career.aspx"&gt;I mentioned before&lt;/a&gt; about my return to blogging on ryanfarley.com and my renewed passion for programming. I've found myself moving from blog to blog reading things that continue to inspire me. I read a post from Justice Gray, titled "&lt;a target="_blank" href="http://graysmatter.codivation.com/HowIAmBecomingABetterDeveloperPart1OfInfinity.aspx"&gt;How I am becoming a better developer, part 1 of infinity&lt;/a&gt;", that was mentioned on an episode of Hanselminutes. This was a great meme, and although I'm late getting to the table, I wanted to post some thoughts I have on becoming a better developer as well as some goals that I've made for myself.&lt;br /&gt;
&lt;br /&gt;
The following list are some things I am doing to become a better developer:&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;&lt;font size="4"&gt;1.&lt;/font&gt; Find/Rediscover Your Passion&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
I've always believed that to be a great developer you &lt;span style="font-style: italic;"&gt;have&lt;/span&gt; to have the passion. What is passion? You know, it's that itch you get as you sit on the couch with your wife (or your husband) watching crappy reality TV and you can't break your thoughts away from sneaking off to write some code. It's that desire you feel to know all there is to know about your language, the framework, emerging new technologies, etc - &lt;span style="font-style: italic;"&gt;just because it is fun to know it&lt;/span&gt;. It's that code that is always in your head, just dying to get out. You're not content with put in 8 hours a day writing code, you just have to find that extra time to do it just because you enjoy it. So, how do you rediscover that (or find it if you've never had it?). I think the rest of this list will help with that. I'd recommend starting with Hanselminutes show #72, &lt;a href="http://www.hanselminutes.com/default.aspx?showID=90" target="_blank"&gt;Be a Better Developer in 6 Months&lt;/a&gt;. Then, make some goals for yourself.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;My goal:&lt;/span&gt; Keep doing the rest of this list to keep the passion. At the end of the year, add new goals.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;/blockquote&gt; &lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;&lt;font size="4"&gt;2.&lt;/font&gt; Remove Distractions&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
There's always things to get in your way of improving yourself and staying focused on your goals. If you work at your home, like me, &lt;span style="font-weight: bold;"&gt;turn off the TV&lt;/span&gt;, shut the office door, establish a "work mode" that separates itself from "home mode". I find it helps to turn off notification sound from &lt;a target="_blank" href="http://www.twhirl.org/"&gt;Twhirl&lt;/a&gt; (or whatever Twitter client you use) as well as other distracting notifications. I found that my eyes would automatically shift to the bottom right corner of my monitor every time that "ping" sound would occur. I think part of "removing distractions" involved establishing routine to some degree. Instead of doing things like going through subscribed RSS feeds periodically throughout the day, disrupting your focus on real work, have a set time at the beginning of each day to catch up on that reading. Then you can stay better focused the rest of the day.  &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;My goal:&lt;/span&gt; Keep the TV off. Make work time a little more "formal" to stay focused. Establish a work mode routine and stick to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/blockquote&gt; &lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;&lt;font size="4"&gt;3.&lt;/font&gt; Listen to Podcasts &amp;amp; Read Blogs&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
A long while back, I would listen to &lt;a href="http://dotnetrocks.com/" target="_blank"&gt;DotNetRocks&lt;/a&gt;, but I stopped and that time got replaced with other things. After hearing about the start of the &lt;a href="http://herdingcode.com/" target="_blank"&gt;HerdingCode&lt;/a&gt; podcast on Twitter, I ended up giving it a try and &lt;span style="font-style: italic; font-weight: bold;"&gt;loved it&lt;/span&gt;. I was feeling interested in the topics they were talking about and found myself wanting to dig into the topics discussed after the show. It was great. I've known of &lt;a href="http://hanselminutes.com/" target="_blank"&gt;Hanselminutes&lt;/a&gt; for quite some time from &lt;a href="http://hanselman.com/" target="_blank"&gt;Scott's blog&lt;/a&gt;, but never really gave it a try. So, I threw a bunch of episodes of that and &lt;a target="_blank" href="http://dotnetrocks.com/"&gt;DotNetRocks&lt;/a&gt; on my Zune, as well as the &lt;a target="_blank" href="http://deepfriedbytes.com/"&gt;Deep Fried Bytes&lt;/a&gt; podcast that was starting up around that same time. The result was not exactly what I expected. I &lt;span style="font-style: italic;"&gt;was&lt;/span&gt; expecting to enjoy listening to these, but it ended up in more than just that. I was feeling inspired. I was feeling excited and couldn't wait to jump into whatever the topic was for the show. Maybe the reason why I thought it was so great is because I do work out of my house. The rest of my development team lives in another state. Being able to hear development related discussions like these is just not the sort of thing I hear around my house (&lt;span style="font-style: italic;"&gt;but we're working on that, hehe&lt;/span&gt;). The same can be said for reading blogs. There is always just so much to learn. I've never had a problem with keeping up with reading blogs.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;My goal:&lt;/span&gt; Listen to a new podcast each morning (weekdays). I've started getting up earlier than I would have to give myself enough time to do a 30-45 minute power walk each morning. The fresh air does wonders, but it also gives me dedicated time to listen to a podcast while walking.&lt;br /&gt;
&lt;br /&gt;
&lt;/blockquote&gt; &lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;&lt;font size="4"&gt;4.&lt;/font&gt; Blog&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
I've taken the first step here with reviving my ryanfarley.com blog. My belief is that, while you can learn a lot from reading from other blogs, you'll learn 10x that by writing posts yourself. The process of thinking through a topic enough to write about it is far more valuable than just reading about that same topic. Any time you can "teach" others, you'll end up growing as a developer by leaps and bounds. This has been my experience throughout my entire career, and I do love teaching others. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;My goal:&lt;/span&gt; Keep posting reularly on this blog (and my &lt;a href="http://customerfx.com/pages/crmdeveloper/" target="_blank"&gt;CRM Developer blog&lt;/a&gt; too). I'm not going to set a specific number or anything, I'm ok with just saying "regularly" :-) Feel free to &lt;a href="http://ryanfarley.com/blog/contact.aspx"&gt;contact me&lt;/a&gt; and give me a push if "regularly" seems "less-regular".&lt;br /&gt;
&lt;br /&gt;
&lt;/blockquote&gt; &lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;&lt;font size="4"&gt;5.&lt;/font&gt; Learn a New Technology Each Month&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
For me, this is something that without questions comes out of listening to podcasts. Since listening to podcasts, I've found that I really love &lt;a href="http://subsonicproject.com/" target="_blank"&gt;SubSonic&lt;/a&gt;, ASP.NET MVC, LINQ, &amp;amp; WPF - which are all things I never really took the time to get into before. The problem is that there are just so many things I want to really learn well and I need some focus or I won't learn enough of any of them. Along the same lines as this, I've established at my company weekly developer meetings. We take an hour or two each Thursday and do some internal training. This has been a great way for me to stay focused and current on new things with a dedicated time for me, and my team, to improve ourselves.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;My goal:&lt;/span&gt; Take the time to learn a new technology every month. Create a side-project using that technology as a reason to learn it. Stick to planned, weekly, developer training sessions with the development team at my company.&lt;br /&gt;
&lt;br /&gt;
&lt;/blockquote&gt; &lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;&lt;font size="4"&gt;6.&lt;/font&gt; Get Involved in an Open Source Project&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
On the Hanselminutes episode #72 that I mentioned earlier, Scott and Carl talk about how the best thing you can do to be a better programmer is read. Not reading books, but reading other people's code. I'll take that one a step further. Not only does reading other people's code help you become a better programmer, but getting involved in writing the code as well will take you even further. &lt;a href="http://ryanfarley.com/blog/archive/2008/07/25/the-relaunch-of-ryanfarley.com-and-how-twitter-helped-my-career.aspx"&gt;While recently migrating&lt;/a&gt; my .Text blog to &lt;a target="_blank" href="http://subtextproject.com/"&gt;Subtext&lt;/a&gt;, I dug though probably most of the Subtext source (and was very familiar with the .Text code that it was forked from). I learned quite a bit looking at the code and a huge benefit of that is the ability to jump in and contribute to the Subtext project. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;My goal:&lt;/span&gt; Pick an open-source project to contribute to over the year.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/blockquote&gt; &lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight: bold;"&gt;&lt;font size="4"&gt;7.&lt;/font&gt; Seek out Local .NET Groups or Nerd Dinners&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;
This one is a big one for people like me that work by themselves in their home. I mentioned earlier that the rest of my team all work in another state. I work out of my home and have a lot of online conferences and meetings as we work on projects together. However, I don't get the social "geek" atmosphere with my co-workers (except when I go out of town to meet with them - which is great). I've never really taken the time to get involved with the other local Arizona geeks. Just having the ability to network with other local .NET geeks and have meaningful conversations about programming topics would do wonders for keeping the passion and focus.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;My goal:&lt;/span&gt; Seek out my local .NET users group and attend as much as possible. Take the time to meet up with others at local nerd diner meetups.&lt;br /&gt;
&lt;br /&gt;
&lt;/blockquote&gt; &lt;br /&gt;
Well, there you go. My thoughts on ways to improve myself as a developer and my goals to do it. Wish me luck.&lt;img src="http://ryanfarley.com/blog/aggbug/38126.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Farley</dc:creator>
            <guid>http://ryanfarley.com/blog/archive/2008/07/30/becoming-a-better-developer.aspx</guid>
            <pubDate>Wed, 30 Jul 2008 07:52:03 GMT</pubDate>
            <comments>http://ryanfarley.com/blog/archive/2008/07/30/becoming-a-better-developer.aspx#feedback</comments>
            <slash:comments>16</slash:comments>
            <wfw:commentRss>http://ryanfarley.com/blog/comments/commentRss/38126.aspx</wfw:commentRss>
            <trackback:ping>http://ryanfarley.com/blog/services/trackbacks/38126.aspx</trackback:ping>
        </item>
    </channel>
</rss>