<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>.NET</title>
        <link>http://geekswithblogs.net/jwhitehorn/category/4679.aspx</link>
        <description>.NET</description>
        <language>en-US</language>
        <copyright>Jason Whitehorn</copyright>
        <managingEditor>jason.whitehorn@gmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>The Wonders Of InternalsVisibleTo</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2007/11/09/116750.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2007/11/09/The-Wonders-Of-InternalsVisibleTo.aspx"&gt;http://jason.whitehorn.ws/2007/11/09/The-Wonders-Of-InternalsVisibleTo.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I do not know how I missed this, but just today I found out that you can expose an assembly's internal methods/properties/classes to a "friend" assembly. Normally internals are only accessible to members of the same assembly, and are often used to hide "plumbing" methods and utilities classes. &lt;br /&gt;
&lt;br /&gt;
For many reasons you often want to separate your code into multiple assemblies, perhaps one for each application layer or some other logical boundary. A problem arises when two or more assemblies need access to each others internals. Prior to .NET 2.0 you had two choices, either expose these plumbing methods as public, or lump as much of your code into one assembly as was needed to keep the plumbing internal.&lt;br /&gt;
&lt;br /&gt;
In comes .NET 2.0's &lt;a href="http://www.marshalbyrefobject.net/wiki/System.Runtime.CompilerServices.InternalsVisibleToAttribute.ashx"&gt;InternalsVisibleTo&lt;/a&gt; attribute. This attribute is applied on the assembly level, and allows the assembly to give internal access to specific assemblies. &lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
Say you have two assemblies, &lt;span style="font-weight: bold;"&gt;MyExample.DomainObjects&lt;/span&gt; &amp;amp; &lt;span style="font-weight: bold;"&gt;MyExample.ServiceLayer&lt;/span&gt;. In the DomainObjects assembly you have the following abstract class:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;namespace MyExample.DomainObjects{&lt;br /&gt;     public abstract class DomainObject{&lt;br /&gt;          //.... other things....&lt;br /&gt;          public virtual DateTime LastModifiedDate{&lt;br /&gt;               get { ... }&lt;br /&gt;               internal set { ... }&lt;br /&gt;          }&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
In the above example you would like to have your service layer in a separate assembly from you domain objects. You would also like to have a LastModifiedDate property for each of your domain objects, but you would prefer if it was only settable by your service layer.&lt;br /&gt;
&lt;br /&gt;
This is were the InternalsVisibleTo comes in handy. In the DomainObjects assembly you can added the InternalsVisbleTo attribute to give only the ServiceLayer assembly access to any and all internal items. For unsigned assemblies the attribute would look like:&lt;br /&gt;
&lt;pre class="code"&gt;[assembly: InternalsVisibleTo("MyExample.ServiceLayer")]&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
This is straight forward when the target assembly is unsigned, but gets a little more difficult when the target assembly is signed. For signed assemblies you will need the assembly's public key. This is not to be confused with the assembly's public key &lt;span style="font-weight: bold;"&gt;token&lt;/span&gt;, which is often what you see. To acquire the public key of a signed assembly you will need the "sn.exe" tool that ships with Visual Studio. &lt;br /&gt;
&lt;br /&gt;
From the "Visual Studio Command Prompt":&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;sn -Tp c:\Users\jason\projects\MyExample\MyExample.ServiceLayer.dll&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt; NOTE:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;the "sn" command takes a big "T" and a little "p" for the switch, and you will need to replace my example path with your own ;-)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Whats pops out of this handy little program is both the public key, and the public key token. The one we needs is the longer one, the public key. With this in hand we can now add the appropriate attribute to our DomainObjects assembly.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;[assembly: InternalsVisibleTo("MyExample.ServiceLayer, PublicKey=0024000004809{key shortened for readability}30a09825a6999")]&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt; NOTE:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;The public key is &lt;/span&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;much &lt;/span&gt;&lt;span style="font-style: italic;"&gt;longer than what is shown above. The above sample is intentionally incorrect for legibility. For this to work you will need to copy and paste the public key in its entirety.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
With the public key added to the assembly name on the attribute our example ServiceLayer assembly can access the internals of the DomainObjects assembly. &lt;br /&gt;
&lt;br /&gt;
Additionally, since the InternalsVisibleTo attribute references the friend assembly by its string name, no real dependency is created from our DomainObjects assembly to our ServiceLayer assembly. The DomainObjects assembly will continue to work with or without the ServiceLayer assembly present.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116750"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116750" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/116750.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2007/11/09/116750.aspx</guid>
            <pubDate>Sat, 10 Nov 2007 02:53:30 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2007/11/09/116750.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/116750.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/116750.aspx</trackback:ping>
        </item>
        <item>
            <title>Enable MS DTC on Windows Vista</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2007/10/31/116504.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2007/10/31/Enable-MS-DTC-On-Windows-Vista.aspx"&gt;http://jason.whitehorn.ws/2007/10/31/Enable-MS-DTC-On-Windows-Vista.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To enable MS DTC on Windows Vista simply follow the instructions from:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://technet2.microsoft.com/windowsserver2008/en/library/1f6d0a27-533b-4516-8656-b492f1649e9f1033.mspx?mfr=true"&gt;http://technet2.microsoft.com/windowsserver2008/en/library/1f6d0a27-533b-4516-8656-b492f1649e9f1033.mspx?mfr=true&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
MS DTC appears to be required to use System.Transactions against SQL Server, and is disabled by default.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116504"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116504" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/116504.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2007/10/31/116504.aspx</guid>
            <pubDate>Thu, 01 Nov 2007 03:10:18 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2007/10/31/116504.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/116504.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/116504.aspx</trackback:ping>
        </item>
        <item>
            <title>A Possible Solution To The .NET 3.5/Visual Studio 2005 Feud</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2007/07/03/113660.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2007/07/03/A-Possible-Solution-To-The-NET-35Visual-Studio-2005-Feud.aspx"&gt;http://jason.whitehorn.ws/2007/07/03/A-Possible-Solution-To-The-NET-35Visual-Studio-2005-Feud.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In &lt;a href="http://geekswithblogs.net/jwhitehorn/archive/2007/06/23/113412.aspx"&gt;my previous post&lt;/a&gt; I discussed a problem of developing ASP.NET 2.0 applications in Visual Studio 2005, while having the .NET 3.5 framework installed. In summation, the issue was because Visual Studio 2005 was linking against a library that shipped with .NET 3.5 instead of the explicitly referenced version from the web.config. &lt;br /&gt;
&lt;br /&gt;
The comments of one reader of &lt;a href="http://geekswithblogs.net/jwhitehorn/archive/2007/06/23/113412.aspx"&gt;my previous post&lt;/a&gt; mentioned using &lt;a href="http://msdn2.microsoft.com/en-us/library/eftw1fys.aspx"&gt;binding redirection&lt;/a&gt; to resolve the issue. In short, it looks like they were correct. As best as I can tell, binding redirection does in fact fix this issue.&lt;br /&gt;
&lt;br /&gt;
Binding redirection is the ability to take a pre-compiled application and tell the loader to link against a different version of a library than the application was originally built with. In our case, we would need to add the following configuration to our web.config.&lt;br /&gt;
&lt;pre class="code"&gt;&amp;lt;runtime&amp;gt;&lt;br /&gt;    &amp;lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&amp;gt;&lt;br /&gt;      &amp;lt;dependentAssembly&amp;gt;&lt;br /&gt;        &amp;lt;assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/&amp;gt;&lt;br /&gt;        &amp;lt;bindingRedirect oldVersion="2.0.0.0" newVersion="1.0.61025.0"/&amp;gt;&lt;br /&gt;      &amp;lt;/dependentAssembly&amp;gt;&lt;br /&gt;    &amp;lt;/assemblyBinding&amp;gt;&lt;br /&gt;  &amp;lt;/runtime&amp;gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The above configuration tells .NET to use System.Web.Extensions version 1.0.61025 instead of version 2.0.0.0. While the above does pose to be a solution to the problem, it is concerning that this would be needed at all.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113660"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113660" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/113660.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2007/07/03/113660.aspx</guid>
            <pubDate>Tue, 03 Jul 2007 21:12:30 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2007/07/03/113660.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/113660.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/113660.aspx</trackback:ping>
        </item>
        <item>
            <title>NHibernate Criteria Queries</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2007/06/30/113603.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2007/06/30/NHibernate-Criteria-Queries.aspx"&gt;http://jason.whitehorn.ws/2007/06/30/NHibernate-Criteria-Queries.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;&lt;a href="http://www.nhibernate.org"&gt;NHibernate's&lt;/a&gt; support for criteria queries provides an extremely powerful query feature into an easy to use package. NHibernate has a rather complete manual that covers criteria queries, which you can checkout &lt;a href="http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/querycriteria.html"&gt;here.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The NHibernate documentation has a ton of information packed within it, and can be a little overwhelming for those who are new to NHibernate. So, as an argumentation to the documentation for criteria searching, I will provide a really basic overview of how things work.&lt;/p&gt;
&lt;p&gt;The NHibernate session exposes a method called "CreateCriteria", which accepts a Type and returns an ICriteria. This is the starting point for any criteria query. The Type you pass the method, is the same Type that you are querying for. For example, if you have a business object call "Customer" that we want to search for using criteria, you would:&lt;/p&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;ICriteria crit = session.CreateCriteria(typeof(Customer));&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;Now that you have created an ICriteria object to represent your search, you need to start specifying various criteria for the object NHibernate will fetch. This is were the "Add" method comes in handy. &lt;/p&gt;
&lt;p&gt;The Add method accepts any ICriterion object, but to help you along NHibernate provides the "Expression" object which has many static methods to help you form your criteria. Continuing with our running example, if you want to select customers who are older than 21 years of age you would:&lt;/p&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;crit.Add(Expression.Gt("Age", 21));&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;The above code tell NHibernate that the "Age" property of our Customer object needs to be greater than the value 21. In the above manor, you can use the Add method and the Expression object to specify exactly which objects you want to retrieve.&lt;/p&gt;
&lt;p&gt;To actually fetch our objects from the database, you execute the "List" method on the ICriteria object.&lt;/p&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;IList&lt;customer&gt; results = crit.List&lt;customer&gt;();&lt;br /&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;p&gt;There are many more capabilities of criteria queries in NHibernate that I have not even touched upon, which you can read more about in the official NHibernate documentation. &lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113603"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113603" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/113603.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2007/06/30/113603.aspx</guid>
            <pubDate>Sat, 30 Jun 2007 18:34:44 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2007/06/30/113603.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/113603.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/113603.aspx</trackback:ping>
        </item>
        <item>
            <title>Parsing RSS From C#</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2007/06/26/113488.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2007/06/26/Parsing-RSS-From-C.aspx"&gt;http://jason.whitehorn.ws/2007/06/26/Parsing-RSS-From-C.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I set out to write a RSS parser in C#. I know that several existing libraries are available for .NET that parse RSS streams, but out of curiosity I wanted to give it a go anyway.&lt;br /&gt;
Before I get started, for those interested in RSS libraries for .NET checkout  &lt;a href="http://www.rssdotnet.com/"&gt;RSS.NET&lt;/a&gt; or  &lt;a href="http://www.perfectxml.com/RSSConnect/"&gt;RSSConnect&lt;/a&gt;, to just name two.&lt;br /&gt;
&lt;br /&gt;
As .NET developers we have some really powerful tools available to us that are built directly into the .NET framework. Take, for example, Serialization. In .NET we can turn an object into an XML resource using the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx"&gt;XmlSerializer&lt;/a&gt; class, provided that the class is &lt;a href="http://msdn2.microsoft.com/en-us/library/system.serializableattribute.aspx"&gt;Serializable&lt;/a&gt;. In fact, the XmlSerializer object will even attempt to populate an object from an XML resource.&lt;br /&gt;
&lt;br /&gt;
Visual Studio ships with a tool called XSD which can turn an XML Schema Definition into a C# class. Knowing that RSS is expressed as an XML resource, I set out to find an XSD for RSS. After some searching I found &lt;a href="http://weblogs.asp.net/wkriebel/archive/2004/03/07/85642.aspx"&gt;this site&lt;/a&gt;, which contains an XSD for RSS that the site's author wrote. For posterity I have placed a mirror of that file on my own site, which you can find &lt;a href="http://whitehorn.ws/files/jason/rss/rss20.xsd"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Before continuing on, I need to pause and look ahead. The XSD that I found did not work out of the box, and I had to make a small modification to get it to work. I removed a reference to the RSS schema namespace from the XSD. The modified XSD can be downloaded from &lt;a href="http://whitehorn.ws/files/jason/rss/RSSv20.xsd"&gt;here&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Now, armed with an XSD, we can have the XSD program make some classes for us. From a command prompt (preferable the "Visual Studio Command Prompt" command prompt) type:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;xsd RSS20.xsd /classes&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Provided that RSS20.xsd is the name of the RSS XSD, and that you are currently in the same directory as RSS20.xsd, the XSD program should output a single file called RSS20.cs. The C# source file that XSD produced contains a class definition for each RSS entity, most notable the root node called "rss".&lt;br /&gt;
&lt;br /&gt;
With classes that represent RSS, we can now use the XmlSerializer object to easily populate an object with RSS data. For example: &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;     string rssXml = "... your rss data here ...";&lt;br /&gt;     XmlSerializer helper = new XmlSerializer(typeof(rss));&lt;br /&gt;     rss obj = (rss)helper.Deserialize(new StringReader(rssXml));&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The above code snippet, will create an rss instance called "obj" from raw RSS data. But, you don't want to have to do this everytime you want to parse RSS. Instead, it would be helpful if that logic was encapsulated by the rss object. Fortunately, the classes produced by the XSD program are all partial classes. So, in a separate .cs file, we can re-declare the rss class and expand upon its functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;//declare another portion of the "rss" object.&lt;br /&gt;public partial class rss{&lt;br /&gt;     //add more methods to "rss" here&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Ideally it would be nice to have both a method to turn an RSS stream into an rss object, and a method to output RSS from an rss object. For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;public partial class rss{&lt;br /&gt;&lt;br /&gt;        public static rss Parse(string rssXml) {&lt;br /&gt;            //turn an RSS string, into an rss object.&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public override string ToString() {&lt;br /&gt;            //turn the rss object into a RSS string.&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The above two methods can both be implemented using the XmlSerializer object, as it provides methods to serialize and deserialize and object. I ended up with the following implementation.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;public partial class rss{&lt;br /&gt;&lt;br /&gt;        public static rss Parse(string rssXml) {&lt;br /&gt;            return (rss)Serializer.Deserialize(new StringReader(rssXml));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public override string ToString() {&lt;br /&gt;            string result;&lt;br /&gt;            using (StringWriter sw = new StringWriter()) {&lt;br /&gt;                Serializer.Serialize(sw, this);&lt;br /&gt;                result = sw.ToString();&lt;br /&gt;            }&lt;br /&gt;            return result;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private static XmlSerializer Serializer {&lt;br /&gt;            get {&lt;br /&gt;                if (_serializer == null)&lt;br /&gt;                    _serializer = new XmlSerializer(typeof(rss));&lt;br /&gt;                return _serializer;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        private static XmlSerializer _serializer;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The above implementation, combined with the output from the XSD program, is a functional RSS parser. The above code can be used to process blog output, or price feeds from your favorite online retailer.&lt;br /&gt;
&lt;br /&gt;
As an added bonus, I wrote two additional methods for rss from those outlined above.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;        //optionally, you can add these two methods to "rss".&lt;br /&gt;        public static rss CreateFrom(Uri location) {&lt;br /&gt;            rss result;&lt;br /&gt;            using (WebClient helper = new WebClient()) {&lt;br /&gt;                string rawRss = helper.DownloadString(location);&lt;br /&gt;                result = Parse(rawRss);&lt;br /&gt;            }&lt;br /&gt;            return result;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static rss CreateFrom(string location) {&lt;br /&gt;            return CreateFrom(new Uri(location));&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
For those interested, a compiled version of this code can be download from &lt;a href="http://whitehorn.ws/files/jason/rss/net.MarshalByRefObject.Rss.dll"&gt;here&lt;/a&gt;.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113488"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113488" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/113488.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2007/06/26/113488.aspx</guid>
            <pubDate>Wed, 27 Jun 2007 03:07:55 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2007/06/26/113488.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/113488.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/113488.aspx</trackback:ping>
        </item>
        <item>
            <title>Visual Studio 2005 and .NET 3.5 Don't Play Well Together</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2007/06/23/113412.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2007/06/23/Visual-Studio-2005-And-NET-35-Dont-Play-Well-Together.aspx"&gt;http://jason.whitehorn.ws/2007/06/23/Visual-Studio-2005-And-NET-35-Dont-Play-Well-Together.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As many of you have, I also have experimented with the pre-releases of .NET 3.5 and Visual Studio codenamed Orcas. I, for better or worse, installed this pre-release software on my primary development machine which has Visual Studio 2005.&lt;br /&gt;
&lt;br /&gt;
Despite having .NET 3.5 installed on my machine, my primary development occurred in .NET 2.0 via Visual Studio 2005. I had not experienced any problems with this setup until the other day. While attempting to build and publish an ASP.NET 2.0 website with AJAX extensions, I ran into a cryptic server error when executing the site on a staging server. The error was:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;Could not load file or assembly 'System.Web.Extensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' &lt;br /&gt;or one of its dependencies. The system cannot find the file specified.&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The System.Web.Extensions assembly is the ASP.NET AJAX assembly, so at first I simply thought that the staging server did not have AJAX extensions installed. After installing the AJAX extensions, the issue remained unresolved. A quick look in the machine's GAC showed that it had version 1.0.61025.0, which is the latest version. Inspection of my development machine's GAC showed both 1.0.61025.0 and 2.0.0.0 installed.&lt;br /&gt;
&lt;br /&gt;
At this point I was puzzled how my machine had an unofficial version of AJAX extensions, and how my website was referencing it. Next I looked at the web.config of my site to see if I could just change the referenced version to 1.0. However, inspection of the web.config reveled:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;&lt;br /&gt;&amp;lt;add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&amp;gt; &lt;br /&gt;&amp;lt;/add&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
As it turned out, I was already explicitly referencing the correct version. As you can imagine, at this point I was extremely puzzled. I even attempted a few cleans and rebuilds of the site, but to no avail. After some time, I realized that the 2.0.0.0 version of System.Web.Extensions was something that shipped with .NET 3.5, and despite my explicit reference to 1.0.61025.0 Visual Studio 2005 was linking against this other version. The only way to resolve this issue was to uninstall Visual Studio codenamed Orcas and .NET 3.5.&lt;br /&gt;
&lt;br /&gt;
I do not know if the fault lies with Visual Studio 2005, or something with the .NET 3.5 framework. But, whichever component is at fault, I hope that this issue is resolved before the final version of .NET 3.5 ships.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113412"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113412" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/113412.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2007/06/23/113412.aspx</guid>
            <pubDate>Sun, 24 Jun 2007 04:04:02 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2007/06/23/113412.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/113412.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/113412.aspx</trackback:ping>
        </item>
        <item>
            <title>Tail Recursion Revisited</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2007/06/06/113060.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2007/06/06/Tail-Recursion-Revisited.aspx"&gt;http://jason.whitehorn.ws/2007/06/06/Tail-Recursion-Revisited.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A year ago I blogged about &lt;a href="http://geekswithblogs.net/jwhitehorn/archive/2006/06/09/81257.aspx"&gt;Tail Recursion&lt;/a&gt; in C# on .NET 2.0. With the public beta of .NET 3.5 now available, I decided to retry my little experiment.&lt;br /&gt;
&lt;br /&gt;
For the experiment I used Beta 1 of .NET 3.5 (version 3.5.20404), which you can get &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=E3715E6F-E123-428B-8A0F-028AFB9E0322&amp;amp;displaylang=en"&gt;from here&lt;/a&gt;. Using the supplied compiler, I compiled the following C# code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;public class TailTest{&lt;br /&gt;	public static void Main(){&lt;br /&gt;		TailTest f = new TailTest();&lt;br /&gt;		f.DoTail(0);&lt;br /&gt;	}&lt;br /&gt;	public void DoTail(int n){&lt;br /&gt;		int v = n + 1;&lt;br /&gt;		System.Console.WriteLine(v);&lt;br /&gt;		DoTail(v);&lt;br /&gt;	}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
Just running the produced EXE is enough to determine that even with the newest version of Microsoft's compiler, the program has not been optimized for tail recursion. Just to confirm this findings, I went ahead and decompiled the EXE to &lt;a href="http://en.wikipedia.org/wiki/Common_Intermediate_Language"&gt;IL&lt;/a&gt; anyway.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;.class public auto ansi beforefieldinit TailTest&lt;br /&gt;    extends [mscorlib]System.Object&lt;br /&gt;{&lt;br /&gt;    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed&lt;br /&gt;    {&lt;br /&gt;        .maxstack 8&lt;br /&gt;        L_0000: ldarg.0 &lt;br /&gt;        L_0001: call instance void [mscorlib]System.Object::.ctor()&lt;br /&gt;        L_0006: ret &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    .method public hidebysig instance void DoTail(int32 n) cil managed&lt;br /&gt;    {&lt;br /&gt;        .maxstack 2&lt;br /&gt;        .locals init (&lt;br /&gt;            [0] int32 num)&lt;br /&gt;        L_0000: nop &lt;br /&gt;        L_0001: ldarg.1 &lt;br /&gt;        L_0002: ldc.i4.1 &lt;br /&gt;        L_0003: add &lt;br /&gt;        L_0004: stloc.0 &lt;br /&gt;        L_0005: ldloc.0 &lt;br /&gt;        L_0006: call void [mscorlib]System.Console::WriteLine(int32)&lt;br /&gt;        L_000b: nop &lt;br /&gt;        L_000c: ldarg.0 &lt;br /&gt;        L_000d: ldloc.0 &lt;br /&gt;        L_000e: call instance void TailTest::DoTail(int32)&lt;br /&gt;        L_0013: nop &lt;br /&gt;        L_0014: ret &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    .method public hidebysig static void Main() cil managed&lt;br /&gt;    {&lt;br /&gt;        .entrypoint&lt;br /&gt;        .maxstack 2&lt;br /&gt;        .locals init (&lt;br /&gt;            [0] class TailTest test)&lt;br /&gt;        L_0000: nop &lt;br /&gt;        L_0001: newobj instance void TailTest::.ctor()&lt;br /&gt;        L_0006: stloc.0 &lt;br /&gt;        L_0007: ldloc.0 &lt;br /&gt;        L_0008: ldc.i4.0 &lt;br /&gt;        L_0009: callvirt instance void TailTest::DoTail(int32)&lt;br /&gt;        L_000e: nop &lt;br /&gt;        L_000f: ret &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
From my &lt;a href="http://geekswithblogs.net/jwhitehorn/archive/2006/06/09/81257.aspx"&gt;previous discussion&lt;/a&gt;, we can see that the resulting IL lacks the "tail.". With all the innovation in C# for the upcoming release of .NET 3.5, I was hoping that the outcome from my experiment would have been different.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113060"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113060" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/113060.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2007/06/06/113060.aspx</guid>
            <pubDate>Thu, 07 Jun 2007 03:05:11 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2007/06/06/113060.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/113060.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/113060.aspx</trackback:ping>
        </item>
        <item>
            <title>Throwing More Than Just Exceptions</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2007/01/24/104368.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2007/01/24/Throwing-More-Than-Just-Exceptions.aspx"&gt;http://jason.whitehorn.ws/2007/01/24/Throwing-More-Than-Just-Exceptions.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is a little known fact (and probably for the best) that the CLR can throw and catch more than just System.Exception and its children. In fact, the CLR can use any type as if it was an Exception.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="code-parent"&gt;
&lt;pre class="code"&gt;.assembly ExceptionTestAssembly {}&lt;br /&gt;&lt;br /&gt;.class public ExceptionTest { //custom class&lt;br /&gt;   //note that ExceptionTest does NOT extend System.Exception&lt;br /&gt;  .method public void .ctor(){&lt;br /&gt;    .maxstack 1&lt;br /&gt;    ret&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  .method static void main() il managed{&lt;br /&gt;      .entrypoint //program entry point...&lt;br /&gt;      .try {&lt;br /&gt;        newobj     instance void ExceptionTest::.ctor()&lt;br /&gt;        throw   //throw a random object&lt;br /&gt;&lt;br /&gt;      } catch ExceptionTest { //catch the random object&lt;br /&gt;        pop&lt;br /&gt;        ldstr "Random object caught"&lt;br /&gt;        call void [mscorlib]System.Console::WriteLine(string)&lt;br /&gt;        leave.s    OUT&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;      OUT: ret&lt;br /&gt;  }&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
In the above code example I have defined my own class (which does &lt;strong&gt;not&lt;/strong&gt; extend System.Exception), and both throw and catch it. This code sample was written in IL because every other .NET language does not allow throwing random objects.&lt;br /&gt;
&lt;br /&gt;
What is the point of this, you ask? Nothing more than to provide insight into the CLR. I would not, and am glad that C# does not allow you too, actual do this. While possible, it violates the &lt;a href="http://en.wikipedia.org/wiki/Common_Type_System"&gt;CTS&lt;/a&gt; contract that good .NET languages abide by.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=104368"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=104368" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/104368.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2007/01/24/104368.aspx</guid>
            <pubDate>Wed, 24 Jan 2007 07:05:00 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2007/01/24/104368.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/104368.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/104368.aspx</trackback:ping>
        </item>
        <item>
            <title>Cookie Renaming in ASP.NET</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2007/01/20/104043.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2007/01/21/Cookie-Renaming-In-ASPNET.aspx"&gt;http://jason.whitehorn.ws/2007/01/21/Cookie-Renaming-In-ASPNET.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ASP.NET you can seamlessly rename cookies on the fly with the help the PreSendRequestHeaders and BeginRequest events of the HttpApplication class. &lt;br /&gt;
&lt;br /&gt;
Both events call EventArgs delegates, with the sender object as a HttpApplication instance.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;     /// &lt;summary&gt;&lt;br /&gt;     /// Called when a cookie is about to be sent to the browser.&lt;br /&gt;     /// &lt;/summary&gt;&lt;br /&gt;     private void CookieOut(object sender, EventArgs e) {&lt;br /&gt;         HttpApplication app = (HttpApplication)sender;&lt;br /&gt;         HttpCookie cookie = app.Response.Cookies["ASP.NET_SessionId"];&lt;br /&gt;         if (cookie != null) {&lt;br /&gt;             app.Response.Cookies.Remove("ASP.NET_SessionId");&lt;br /&gt;             cookie.Name = "fooBar";&lt;br /&gt;             app.Response.Cookies.Add(cookie);&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; &lt;/pre&gt;
&lt;br /&gt;
The above method will find a cookie of a specific name, and rename it to something else. In this example, everything in ASP.NET that occurs before the HttpApplication.PreSendRequestHeaders is called will refer to the cookie as "ASP.NET_SessionId". By the time the cookie reaches the browser, it is called "fooBar".&lt;br /&gt;
&lt;br /&gt;
This can be useful when you cannot otherwise control the name of a cookie. The above example is only half of the solution. The cookie will need to be renamed again when it returns from the browser.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;      /// &lt;summary&gt;       /// Called when a cookie is coming into the application.       /// &lt;/summary&gt;       private void CookieIn(object sender, EventArgs e) {           HttpApplication app = (HttpApplication)sender;           HttpCookie cookie = app.Request.Cookies["fooBar"];           if (cookie != null) {               app.Request.Cookies.Remove("fooBar");               cookie.Name = "ASP.NET_SessionId";               app.Request.Cookies.Add(cookie);           }       }    &lt;/pre&gt;
&lt;br /&gt;
With the help of the HttpAplication.BeginRequest event, the above method will rename the otherwise named "fooBar" cookie to its original name. All events occurring after BeginRequest will refer to the cookie as "ASP.NET_SessionId", and will be unaware of what has just occurred.&lt;br /&gt;
&lt;br /&gt;
The only caveat to the above solution, is that each cookie practically has two names. In the above example, user code will never be able to create a cookie named "fooBar", as it is already used by the cookie named "ASP.NET_SessionId".&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=104043"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=104043" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/104043.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2007/01/20/104043.aspx</guid>
            <pubDate>Sat, 20 Jan 2007 07:48:00 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2007/01/20/104043.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/104043.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/104043.aspx</trackback:ping>
        </item>
        <item>
            <title>Google Custom Search Engine</title>
            <link>http://geekswithblogs.net/jwhitehorn/archive/2006/10/27/95183.aspx</link>
            <description>&lt;strong&gt;UPDATE (12/17/2007):&lt;/strong&gt; My blog has moved. This post is now located at: &lt;a href="http://jason.whitehorn.ws/2006/10/28/Google-Custom-Search-Engine.aspx"&gt;http://jason.whitehorn.ws/2006/10/28/Google-Custom-Search-Engine.aspx&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Today I just discovered &lt;a href="http://www.google.com/coop/cse/overview"&gt;Google's custom search engine&lt;/a&gt; program, and quickly setup a &lt;a href="http://www.google.com/coop/cse?cx=005858570544537511402%3A_ddt0xcgo9k"&gt;.NET Search Engine&lt;/a&gt;. I have restricted the list of sites to those that cater to .NET topics including non other than geekswithblogs, in addition to others.&lt;br /&gt;
&lt;br /&gt;
Let me know what you think.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=95183"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=95183" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/jwhitehorn/aggbug/95183.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jason Whitehorn</dc:creator>
            <guid>http://geekswithblogs.net/jwhitehorn/archive/2006/10/27/95183.aspx</guid>
            <pubDate>Fri, 27 Oct 2006 06:39:00 GMT</pubDate>
            <comments>http://geekswithblogs.net/jwhitehorn/archive/2006/10/27/95183.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/jwhitehorn/comments/commentRss/95183.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jwhitehorn/services/trackbacks/95183.aspx</trackback:ping>
        </item>
    </channel>
</rss>