<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.pluralsight.com/community/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Security Briefs</title><link>http://www.pluralsight.com/community/blogs/keith/default.aspx</link><description>by Keith Brown</description><dc:language>en</dc:language><generator>CommunityServer 2008 SP1 (Build: 30619.63)</generator><item><title>Null Strings in ASP.NET Declarative DataSource Updates</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/29/null-strings-in-asp-net-declarative-datasource-updates.aspx</link><pubDate>Fri, 29 Aug 2008 15:42:47 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52773</guid><dc:creator>keith-brown</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52773</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/29/null-strings-in-asp-net-declarative-datasource-updates.aspx#comments</comments><description>&lt;p&gt;I just spent about 15 minutes debugging a problem where a document was getting unexpected nulls where empty strings should have been. Indeed controls like the TextBox have code in them that allows you to set the Text property to null and the TextBox will convert that into an empty string. So it&amp;#39;s a bit counterintuitive that &lt;em&gt;the declarative data source works the opposite way by default&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;When you use a declarative data source to perform a parameterized update that contains string parameters, consider setting ConvertEmptyStringToNull=&amp;#39;false&amp;#39; on your &amp;lt;asp:Parameter&amp;gt; elements, because &lt;em&gt;it&amp;#39;s true by default&lt;/em&gt;! In other words, if a text field contains an empty string, it&amp;#39;ll be sent to your declarative data source not as string.Empty, but as null.&lt;/p&gt; &lt;p&gt;Now I don&amp;#39;t know about you, but I don&amp;#39;t like dealing with nulls if I can avoid it. Especially strings. Unless there&amp;#39;s a clear need to have a null state, I avoid them like the plague not only in my database designs but also in my XML schema designs. Hopefully this helps somebody out!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52773" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Serializable XmlDocument</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/18/serializable-xmldocument.aspx</link><pubDate>Tue, 19 Aug 2008 02:58:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52538</guid><dc:creator>keith-brown</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52538</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/18/serializable-xmldocument.aspx#comments</comments><description>&lt;p&gt;It&amp;#39;s surprising that XmlDocument isn&amp;#39;t marked [Serializable], because it&amp;#39;s very natural to serialize one into a stream. I wanted to put an object into ASP.NET ViewState the other day, and quickly ran into this roadblock, because part of the object included an XmlDocument, which is not serializable. A quick search revealed that most people deal with this problem by storing a string instead. Indeed, that was where I started, but I quickly realized that there are multiple places in my code where I want to do this sort of thing, and I don&amp;#39;t want to have to mess with it in each data structure that contains an XmlDocument.&lt;/p&gt;
&lt;p&gt;So I put together a simple class that holds an XmlDocument and implements ISerializable and called it SerializableXmlDocument. I&amp;#39;m sharing the source code here in the hopes that&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a) somebody will find it useful, and&lt;/p&gt;
&lt;p&gt;b) somebody smarter than I am will point out how I screwed it up and help me make it better.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;SerializableXmlDocument includes implicit conversion operators to make it easy to convert to/from an XmlDocument. It holds the actual document in a property called Value. This &amp;quot;isomorph&amp;quot; pattern is one that I picked up from &lt;a href="http://www.pluralsight.com/community/blogs/craig/default.aspx" target="_blank"&gt;Craig&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While writing this code, I also wrote a helpful extension method for getting a byte array out of a MemoryStream that is exactly the length of the data written to the stream so far (CopyUpToSeekPointer). So don&amp;#39;t go looking in the docs for MemoryStream for this method :) This is obviously not the most efficient way to consume bytes written to a MemoryStream since it copies the data into a new byte array, but it&amp;#39;s very convenient in many scenarios.&lt;/p&gt;
&lt;p&gt;Here is SerializableXmlDocument.cs:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.Serialization;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Pluralsight.Samples&lt;br /&gt;{&lt;br /&gt;    [Serializable]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SerializableXmlDocument : ISerializable&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; SerializableXmlDocument() { }&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; SerializableXmlDocument(XmlDocument &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.Value = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; XmlDocument Value { get; set; }&lt;br /&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; ISerializable implementation&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; SerializableXmlDocument(SerializationInfo info,&lt;br /&gt;                                       StreamingContext context)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] serializedData = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;[])info.GetValue(&lt;span class="str"&gt;&amp;quot;doc&amp;quot;&lt;/span&gt;,&lt;br /&gt;                &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;byte&lt;/span&gt;[]));&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != serializedData)&lt;br /&gt;                &lt;span class="kwrd"&gt;this&lt;/span&gt;.Value = Deserialize(serializedData);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; GetObjectData(SerializationInfo info,&lt;br /&gt;                                  StreamingContext context)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] serializedData = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != Value)&lt;br /&gt;                serializedData = Serialize(Value);&lt;br /&gt;            info.AddValue(&lt;span class="str"&gt;&amp;quot;doc&amp;quot;&lt;/span&gt;, serializedData);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; &lt;span class="kwrd"&gt;implicit&lt;/span&gt; conversion to/from XmlDocument&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;implicit&lt;/span&gt; &lt;span class="kwrd"&gt;operator&lt;/span&gt; SerializableXmlDocument(&lt;br /&gt;            XmlDocument doc)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; SerializableXmlDocument(doc);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;implicit&lt;/span&gt; &lt;span class="kwrd"&gt;operator&lt;/span&gt; XmlDocument(&lt;br /&gt;            SerializableXmlDocument sdoc)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; sdoc.Value;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; Xml serialization helper methods&lt;br /&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] Serialize(XmlDocument doc)&lt;br /&gt;        {&lt;br /&gt;            MemoryStream stream = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream();&lt;br /&gt;            doc.Save(stream);&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; stream.CopyUpToSeekPointer();&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; XmlDocument Deserialize(&lt;span class="kwrd"&gt;byte&lt;/span&gt;[] serializedData)&lt;br /&gt;        {&lt;br /&gt;            XmlDocument doc = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlDocument();&lt;br /&gt;            doc.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream(serializedData, &lt;span class="kwrd"&gt;false&lt;/span&gt;));&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; doc;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;...and here&amp;#39;s the CopyUpToSeekPointer extension method for MemoryStream:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Pluralsight.Samples&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MemoryStreamExtensionMethods&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] CopyUpToSeekPointer(&lt;br /&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt; MemoryStream stream)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="rem"&gt;// copy only the part of the buffer&lt;/span&gt;&lt;br /&gt;            &lt;span class="rem"&gt;// that contains the serialized document&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;long&lt;/span&gt; length = stream.Position;&lt;br /&gt;            &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] buffer = stream.GetBuffer();&lt;br /&gt;            &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] result = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[length];&lt;br /&gt;            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; length; ++i)&lt;br /&gt;                result[i] = buffer[i];&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; result;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;...and here&amp;#39;s a sample object that uses SerializableXmlDocument:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Pluralsight.Samples&lt;br /&gt;{&lt;br /&gt;    [Serializable]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Item&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; SerializableXmlDocument Data { get; set; }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Print()&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Name: {0}&amp;quot;&lt;/span&gt;, Name);&lt;br /&gt;            Console.WriteLine(Data.Value.OuterXml);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;...and here&amp;#39;s a sample program that creates an instance of Item, serializes it, then deserializes it, printing diagnostics along the way to show that it&amp;#39;s working properly.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.Serialization.Formatters.Binary;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Pluralsight.Samples;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; DemoProgram&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;    {&lt;br /&gt;        XmlDocument doc = &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlDocument();&lt;br /&gt;        doc.LoadXml(&lt;span class="str"&gt;&amp;quot;&amp;lt;root&amp;gt;&amp;lt;child&amp;gt;text&amp;lt;/child&amp;gt;&amp;lt;/root&amp;gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        Item item = &lt;span class="kwrd"&gt;new&lt;/span&gt; Item&lt;br /&gt;        {&lt;br /&gt;            Name = &lt;span class="str"&gt;&amp;quot;Testing 123&amp;quot;&lt;/span&gt;,&lt;br /&gt;            Data = doc,&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        &lt;span class="rem"&gt;// print object before serialization&lt;/span&gt;&lt;br /&gt;        item.Print();&lt;br /&gt;&lt;br /&gt;        BinaryFormatter formatter = &lt;span class="kwrd"&gt;new&lt;/span&gt; BinaryFormatter();&lt;br /&gt;        MemoryStream stream = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream();&lt;br /&gt;        formatter.Serialize(stream, item);&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] serializedItem = stream.CopyUpToSeekPointer();&lt;br /&gt;&lt;br /&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Serialized data (base64): {0}&amp;quot;&lt;/span&gt;,&lt;br /&gt;            Convert.ToBase64String(serializedItem));&lt;br /&gt;&lt;br /&gt;        item = (Item)formatter.Deserialize(&lt;br /&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream(serializedItem, &lt;span class="kwrd"&gt;false&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;        &lt;span class="rem"&gt;// print object after deserialization&lt;/span&gt;&lt;br /&gt;        item.Print();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Here&amp;#39;s the output of the previous sample program:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.pluralsight.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/keith/sample_2D00_output_5F00_2.jpg"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" alt="sample-output" src="http://www.pluralsight.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/keith/sample_2D00_output_5F00_thumb.jpg" width="422" border="0" height="214" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Flame away!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52538" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Two-way formatted data binding in ASP.NET</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/15/two-way-formatted-data-binding-in-asp-net.aspx</link><pubDate>Fri, 15 Aug 2008 20:22:37 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52504</guid><dc:creator>keith-brown</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52504</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/15/two-way-formatted-data-binding-in-asp-net.aspx#comments</comments><description>&lt;p&gt;Two way data binding in ASP.NET is easy, just use the Bind expression and data will flow between your web controls and your data source flawlessly. Until that is, you try to use a format string:&lt;/p&gt; &lt;p&gt;Bind(&amp;quot;AmountCharged&amp;quot;, &amp;quot;{0:C}&amp;quot;)&lt;/p&gt; &lt;p&gt;While this displays just as you&amp;#39;d expect (e.g., $200), it doesn&amp;#39;t do so well when you submit an edit that includes the same value ($200):&lt;/p&gt; &lt;p&gt;&lt;span style="font-weight:normal;font-size:14pt;color:maroon;font-family:&amp;#39;Verdana&amp;#39;;"&gt;&lt;i&gt;Input string was not in a correct format.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;I searched around and didn&amp;#39;t find much in the way of a clean solution, but I did solve the problem with just a few lines of code. The trick is to handle the data-bound control&amp;#39;s Updating event. Since I was working with a GridView, my solution looked a bit like this:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:GridView&lt;/span&gt; &lt;span class="attr"&gt;DataSourceID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;#39;myDataSource&amp;#39;&lt;/span&gt;
              &lt;span class="attr"&gt;OnRowUpdating&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;#39;FixFormatting&amp;#39;&lt;/span&gt;
              &lt;span class="attr"&gt;AutoGenerateColumns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;#39;false&amp;#39;&lt;/span&gt;
              &lt;span class="attr"&gt;CellPadding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;3&amp;quot; ...&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Notice the OnRowUpdating handler that I&amp;#39;ve installed in my grid view. That code looks like this:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; FixFormatting(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, GridViewUpdateEventArgs args)
{
    &lt;span class="kwrd"&gt;decimal&lt;/span&gt; amountPaid = ParseDecimal((&lt;span class="kwrd"&gt;string&lt;/span&gt;)args.NewValues[&lt;span class="str"&gt;&amp;quot;AmountPaid&amp;quot;&lt;/span&gt;]);
    args.NewValues[&lt;span class="str"&gt;&amp;quot;AmountPaid&amp;quot;&lt;/span&gt;] = amountPaid;
}&lt;/pre&gt;
&lt;p&gt;When you handle this event, you&amp;#39;re given a dictionary of old and new values, which appear to come directly from the controls (in my case, a TextBox was used to gather the updated data AmountPaid, so the type of object that I found in NewValues[&amp;quot;AmountPaid&amp;quot;] was a string. I wrote a little helper method called ParseDecimal that parses a string into a decimal value, allowing currency characters, decimal points, and thousands separators. I also allowed a blank value to indicate zero:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; ParseDecimal(&lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(&lt;span class="kwrd"&gt;value&lt;/span&gt;))
        &lt;span class="kwrd"&gt;return&lt;/span&gt; 0;
    &lt;span class="kwrd"&gt;return&lt;/span&gt; Decimal.Parse(&lt;span class="kwrd"&gt;value&lt;/span&gt;,
        NumberStyles.AllowThousands |
        NumberStyles.AllowDecimalPoint |
        NumberStyles.AllowCurrencySymbol,
        CultureInfo.InstalledUICulture);
}
&lt;/pre&gt;
&lt;p&gt;This solved the problem quite nicely. Now two-way binding works with formatted data.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52504" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Where to get Password Minder</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/05/where-to-get-password-minder.aspx</link><pubDate>Tue, 05 Aug 2008 17:00:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52369</guid><dc:creator>keith-brown</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52369</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/05/where-to-get-password-minder.aspx#comments</comments><description>&lt;p&gt;We recently updated our website and some links have broken as a result. Here&amp;#39;s the place you should go to get the latest version of Password Minder:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mercury.pluralsight.com/tools.aspx"&gt;http://mercury.pluralsight.com/tools.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sorry for any inconvenience!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52369" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Security/default.aspx">Security</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Identity/default.aspx">Identity</category></item><item><title>Better exception reporting in ASP.NET part 2</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/04/better-exception-reporting-in-asp-net-part-2.aspx</link><pubDate>Mon, 04 Aug 2008 14:11:14 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52349</guid><dc:creator>keith-brown</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52349</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/04/better-exception-reporting-in-asp-net-part-2.aspx#comments</comments><description>&lt;p&gt;This is the third post in a series.&lt;/p&gt; &lt;p&gt;The &lt;a href="http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/asp-net-health-monitoring-doesn-t-log-inner-exception-stack-trace.aspx" target="_blank"&gt;first post&lt;/a&gt; described the problem: ASP.NET wasn&amp;#39;t reporting inner exception stack traces.&lt;/p&gt; &lt;p&gt;The &lt;a href="http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/better-exception-reporting-in-asp-net.aspx" target="_blank"&gt;second post&lt;/a&gt; described my solution.&lt;/p&gt; &lt;p&gt;This post shows the code I used to solve the problem: a custom email provider for the Health Monitoring system in ASP.NET. Enjoy!&lt;/p&gt; &lt;p&gt;Here&amp;#39;s the provider. Note that I opted *not* to build a buffering provider to keep things simple:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MyMailWebEventProvider : WebEventProvider
{
    &lt;span class="kwrd"&gt;string&lt;/span&gt; to;
    &lt;span class="kwrd"&gt;string&lt;/span&gt; from;
    &lt;span class="kwrd"&gt;string&lt;/span&gt; subjectPrefix;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize(&lt;span class="kwrd"&gt;string&lt;/span&gt; name,
        NameValueCollection config)
    {
        &lt;span class="kwrd"&gt;base&lt;/span&gt;.Initialize(name, config);

        to = GetAndRemoveStringAttribute(config, &lt;span class="str"&gt;&amp;quot;to&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;);
        from = GetAndRemoveStringAttribute(config, &lt;span class="str"&gt;&amp;quot;from&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;);
        subjectPrefix = GetAndRemoveStringAttribute(config,
            &lt;span class="str"&gt;&amp;quot;subjectPrefix&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;false&lt;/span&gt;);
    }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ProcessEvent(WebBaseEvent raisedEvent)
    {
        SendMail(raisedEvent);
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SendMail(WebBaseEvent raisedEvent)
    {
        &lt;span class="kwrd"&gt;string&lt;/span&gt; subject = ComputeEmailSubject(raisedEvent);
        &lt;span class="kwrd"&gt;string&lt;/span&gt; body = ComputeEmailBody(raisedEvent);

        MailMessage msg = &lt;span class="kwrd"&gt;new&lt;/span&gt; MailMessage(from, to, subject, body);
        &lt;span class="kwrd"&gt;new&lt;/span&gt; SmtpClient().Send(msg);
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ComputeEmailBody(WebBaseEvent raisedEvent)
    {
        WebRequestErrorEvent errorEvent =
            raisedEvent &lt;span class="kwrd"&gt;as&lt;/span&gt; WebRequestErrorEvent;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != errorEvent)
            &lt;span class="kwrd"&gt;return&lt;/span&gt; ErrorEventFormattingHelper.FormatRequestErrorEvent(errorEvent);
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; raisedEvent.ToString();
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ComputeEmailSubject(WebBaseEvent raisedEvent)
    {
        StringBuilder subjectBuilder = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();

        &lt;span class="rem"&gt;// surface some details in subject about error events&lt;/span&gt;
        WebBaseErrorEvent errorEvent = raisedEvent &lt;span class="kwrd"&gt;as&lt;/span&gt; WebBaseErrorEvent;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != errorEvent)
        {
            Exception unhandledException = errorEvent.ErrorException;

            &lt;span class="rem"&gt;// drill through reflection exceptions to show the root cause&lt;/span&gt;
            TargetInvocationException invocationException =
                unhandledException &lt;span class="kwrd"&gt;as&lt;/span&gt; TargetInvocationException;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != invocationException)
            {
                Exception innerException =
                    DrillIntoTargetInvocationException(invocationException);
                subjectBuilder.AppendFormat(&lt;span class="str"&gt;&amp;quot;{0}&amp;quot;&lt;/span&gt;,
                    (innerException ?? invocationException).GetType().Name);
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != innerException)
                    subjectBuilder.Append(&lt;span class="str"&gt;&amp;quot; (via reflection)&amp;quot;&lt;/span&gt;);
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt; subjectBuilder.Append(unhandledException.GetType().Name);
        }

        &lt;span class="rem"&gt;// if we&amp;#39;ve not got anything better&lt;/span&gt;
        &lt;span class="rem"&gt;// just show the event type in the subject&lt;/span&gt;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (0 == subjectBuilder.Length)
            subjectBuilder.AppendFormat(&lt;span class="str"&gt;&amp;quot;Event type: {0}&amp;quot;&lt;/span&gt;,
                raisedEvent.GetType().Name);

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(subjectPrefix)) {
            subjectBuilder.Insert(0, &lt;span class="str"&gt;&amp;#39; &amp;#39;&lt;/span&gt;);
            subjectBuilder.Insert(0, subjectPrefix);
        }
        &lt;span class="kwrd"&gt;return&lt;/span&gt; subjectBuilder.ToString();
    }

    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;/// Reflection often hides exception details, so we try to drill down&lt;/span&gt;
    &lt;span class="rem"&gt;/// through the plumbing exceptions to find a likely cause&lt;/span&gt;
    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; Exception DrillIntoTargetInvocationException(
        TargetInvocationException outerException)
    {
        Exception innerException = outerException.InnerException;
        TargetInvocationException innerInvocationException =
            innerException &lt;span class="kwrd"&gt;as&lt;/span&gt; TargetInvocationException;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != innerInvocationException)
            &lt;span class="kwrd"&gt;return&lt;/span&gt; DrillIntoTargetInvocationException(innerInvocationException);
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != innerException)
            &lt;span class="kwrd"&gt;return&lt;/span&gt; innerException;
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetAndRemoveStringAttribute(NameValueCollection config,
        &lt;span class="kwrd"&gt;string&lt;/span&gt; attributeName, &lt;span class="kwrd"&gt;bool&lt;/span&gt; required)
    {
        &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; = config.Get(attributeName);
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (required &amp;amp;&amp;amp; &lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(&lt;span class="kwrd"&gt;value&lt;/span&gt;))
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ConfigurationErrorsException(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
                &lt;span class="str"&gt;&amp;quot;Expected attribute {0}, which is missing or empty.&amp;quot;&lt;/span&gt;,
                attributeName));
        config.Remove(attributeName);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Flush()
    {
        &lt;span class="rem"&gt;// nothing to do - this is not a buffering provider&lt;/span&gt;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Shutdown()
    {
        &lt;span class="rem"&gt;// nothing to do here either&lt;/span&gt;
    }
}&lt;/pre&gt;
&lt;p&gt;Here&amp;#39;s a helper class that formats the error messages the way I want to see them. Note that I&amp;#39;ve omitted some fields that I personally didn&amp;#39;t care about, and I&amp;#39;ve reordered things a bit, so you might want to tweak this if you&amp;#39;re going to use it in your own system.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ErrorEventFormattingHelper
{
    &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FormatRequestErrorEvent(
        WebRequestErrorEvent errorEvent)
    {
        CustomEventFormatter formatter = 
            &lt;span class="kwrd"&gt;new&lt;/span&gt; CustomEventFormatter();

        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Unhandled Exception in {0}:&amp;quot;&lt;/span&gt;,
            WebBaseEvent.ApplicationInformation
            .ApplicationVirtualPath));
        formatter.Indent();
        EmitExceptionAtAGlance(formatter, 
            errorEvent.ErrorException);
        formatter.RevertIndent();

        formatter.AppendLine();
        formatter.AppendLine(&lt;span class="str"&gt;&amp;quot;Exception stack trace(s):&amp;quot;&lt;/span&gt;);
        EmitExceptionStackTrace(formatter, 
            errorEvent.ErrorException);

        formatter.AppendLine();
        formatter.AppendLine(&lt;span class="str"&gt;&amp;quot;Event information:&amp;quot;&lt;/span&gt;);
        formatter.Indent();
        EmitEventInfo(formatter, errorEvent);
        formatter.RevertIndent();

        formatter.AppendLine();
        formatter.AppendLine(&lt;span class="str"&gt;&amp;quot;Application information:&amp;quot;&lt;/span&gt;);
        formatter.Indent();
        EmitApplicationInfo(formatter, 
            WebBaseEvent.ApplicationInformation);
        formatter.RevertIndent();

        formatter.AppendLine();
        formatter.AppendLine(&lt;span class="str"&gt;&amp;quot;Process/thread information:&amp;quot;&lt;/span&gt;);
        formatter.Indent();
        EmitProcessInfo(formatter, 
            errorEvent.ProcessInformation);
        formatter.RevertIndent();

        formatter.AppendLine();
        formatter.AppendLine(&lt;span class="str"&gt;&amp;quot;Request information:&amp;quot;&lt;/span&gt;);
        formatter.Indent();
        EmitRequestInfo(formatter, 
            errorEvent.RequestInformation);
        formatter.RevertIndent();

        &lt;span class="kwrd"&gt;return&lt;/span&gt; formatter.ToString();
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EmitEventInfo(
        CustomEventFormatter formatter,
        WebBaseEvent theEvent)
    {
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Event code: {0}&amp;quot;&lt;/span&gt;,
            theEvent.EventCode.ToString(
            CultureInfo.InvariantCulture)));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Event message: {0}&amp;quot;&lt;/span&gt;, 
            theEvent.Message));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Event time: {0}&amp;quot;&lt;/span&gt;, 
            theEvent.EventTime.ToString(
            CultureInfo.InvariantCulture)));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Event ID: {0}&amp;quot;&lt;/span&gt;, 
            theEvent.EventID.ToString(&lt;span class="str"&gt;&amp;quot;N&amp;quot;&lt;/span&gt;, 
            CultureInfo.InvariantCulture)));
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EmitApplicationInfo(
        CustomEventFormatter formatter, 
        WebApplicationInformation appInfo)
    {
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Application domain: {0}&amp;quot;&lt;/span&gt;, 
            appInfo.ApplicationDomain));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Application Virtual Path: {0}&amp;quot;&lt;/span&gt;, 
            appInfo.ApplicationVirtualPath));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Application Physical Path: {0}&amp;quot;&lt;/span&gt;, 
            appInfo.ApplicationPath));
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EmitProcessInfo(
        CustomEventFormatter formatter, 
        WebProcessInformation webProcessInfo)
    {
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Process ID: {0}&amp;quot;&lt;/span&gt;, 
            webProcessInfo.ProcessID.ToString(
            CultureInfo.InvariantCulture)));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Process name: {0}&amp;quot;&lt;/span&gt;, 
            webProcessInfo.ProcessName));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Account name: {0}&amp;quot;&lt;/span&gt;, 
            webProcessInfo.AccountName));
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EmitRequestInfo(
        CustomEventFormatter formatter, 
        WebRequestInformation webRequestInfo)
    {
        &lt;span class="kwrd"&gt;string&lt;/span&gt; name = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (webRequestInfo.Principal != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            name = webRequestInfo.Principal.Identity.Name;

        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Request URL: {0}&amp;quot;&lt;/span&gt;, 
            webRequestInfo.RequestUrl));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Request path: {0}&amp;quot;&lt;/span&gt;, 
            webRequestInfo.RequestPath));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;User name: {0}&amp;quot;&lt;/span&gt;, 
            name ?? &lt;span class="str"&gt;&amp;quot;[ANONYMOUS]&amp;quot;&lt;/span&gt;));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;User host address: {0}&amp;quot;&lt;/span&gt;, 
            webRequestInfo.UserHostAddress));
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EmitExceptionAtAGlance(
        CustomEventFormatter formatter, 
        Exception exception)
    {
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Type: {0}&amp;quot;&lt;/span&gt;, 
            exception.GetType().Name));
        formatter.AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(
            &lt;span class="str"&gt;&amp;quot;Message: {0}&amp;quot;&lt;/span&gt;, 
            exception.Message));
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != exception.InnerException)
        {
            formatter.Indent();
            formatter.AppendLine(&lt;span class="str"&gt;&amp;quot;--&amp;gt;Inner Exception&amp;quot;&lt;/span&gt;);
            EmitExceptionAtAGlance(formatter, 
                exception.InnerException);
            formatter.RevertIndent();
        }
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EmitExceptionStackTrace(
        CustomEventFormatter formatter, Exception exception)
    {
        formatter.AppendLine(exception.StackTrace);

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != exception.InnerException)
        {
            &lt;span class="rem"&gt;// no point indenting&lt;/span&gt;
            &lt;span class="rem"&gt;// since stack traces typically wrap like crazy&lt;/span&gt;
            formatter.AppendLine();
            formatter.AppendLine(&lt;span class="str"&gt;&amp;quot;--&amp;gt;Inner exception stack trace:&amp;quot;&lt;/span&gt;);
            EmitExceptionStackTrace(formatter, exception.InnerException);
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;And finally, here&amp;#39;s a helper class that manages indentation levels for the output email message:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CustomEventFormatter
{
    &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; TabSpaces = 4;

    StringBuilder sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; indentLevel;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; startingNewLine = &lt;span class="kwrd"&gt;true&lt;/span&gt;;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Indent()
    {
        ++indentLevel;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RevertIndent()
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (indentLevel &amp;gt; 0)
            --indentLevel;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Append(&lt;span class="kwrd"&gt;string&lt;/span&gt; text)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (startingNewLine)
            EmitIndent();
        sb.Append(text);
        startingNewLine = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt; lineOfText)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (startingNewLine)
            EmitIndent();
        EmitIndent();
        sb.AppendLine(lineOfText);
        startingNewLine = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; EmitIndent()
    {
        sb.Append(&lt;span class="str"&gt;&amp;#39; &amp;#39;&lt;/span&gt;, TabSpaces * indentLevel);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AppendLine()
    {
        AppendLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToString()
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; sb.ToString();
    }
}
&lt;/pre&gt;
&lt;p&gt;Build this into a library application and reference it in your config file. Here&amp;#39;s an example:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;healthMonitoring&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;providers&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mailWebEventProvider&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyMailWebEventProvider&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;to&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;web-fault@fabrikam.com&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;from&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;website@fabrikam.com&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;buffer&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;subjectPrefix&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[WEB-ERROR]&amp;quot;&lt;/span&gt;
       &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;providers&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;rules&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;All Errors Email&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;eventName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;All Errors&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;provider&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mailWebEventProvider&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;profile&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Default&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;minInstances&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;maxLimit&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Infinite&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;minInterval&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;00:01:00&amp;quot;&lt;/span&gt;
         &lt;span class="attr"&gt;custom&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;rules&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;healthMonitoring&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52349" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Twisted Coronas</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/02/twisted-coronas.aspx</link><pubDate>Sat, 02 Aug 2008 17:33:51 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52330</guid><dc:creator>keith-brown</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52330</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/02/twisted-coronas.aspx#comments</comments><description>&lt;p&gt;Okay it&amp;#39;s Saturday, so let me share something completely nontechnical and fun.&lt;/p&gt; &lt;p&gt;What you need to make these cocktails:&lt;/p&gt; &lt;blockquote&gt;Six pack of &lt;a href="http://www.corona.com/" target="_blank"&gt;Corona Extra&lt;/a&gt;&lt;br /&gt;Bottle of &lt;a href="http://www.bacardi.com/us/en-us/products/additionalproducts/bacardilim%C3%B3n?accessibility=true&amp;amp;marketlanguageid=2" target="_blank"&gt;Bacardi Limon&lt;/a&gt;&lt;br /&gt;Lime&lt;br /&gt;Coctail stirrer (a chopstick works fine)&lt;/blockquote&gt; &lt;p&gt;Pop a slice of lime into a Corona and hand to a friend. Have them drink the neck, then refill with Bacardi Limon (putting the lime in first seems to reduce fizzing). Stir and hand back to them so they can drink it down as it fizzes up a bit.&lt;/p&gt; &lt;p&gt;Mixing rum and beer may sound nasty, but this actually results in a very smooth, tasty drink. It&amp;#39;s our favorite accompaniment when we are playing &lt;a href="http://www.xbox.com/en-us/games/r/rockband/" target="_blank"&gt;Rock Band&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;We took this recipe and applied it to one of our other favorite beers as well: &lt;a href="http://www.epinions.com/content_369863855748" target="_blank"&gt;Honey Moon Summer Ale&lt;/a&gt; (also works with &lt;a href="http://en.wikipedia.org/wiki/Blue_Moon_(beer)" target="_blank"&gt;Blue Moon&lt;/a&gt;, or any other typically orange-flavored beer). Just use &lt;a href="http://www.bacardi.com/us/en-us/products/additionalproducts/bacardio?accessibility=true&amp;amp;marketlanguageid=2" target="_blank"&gt;Barcardi O&lt;/a&gt; instead of Limon.&lt;/p&gt; &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52330" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/42/default.aspx">42</category></item><item><title>Comments</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/comments.aspx</link><pubDate>Fri, 01 Aug 2008 21:38:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52316</guid><dc:creator>keith-brown</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52316</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/comments.aspx#comments</comments><description>&lt;p&gt;We recently switched our blog engine out, and I&amp;#39;m still getting the hang of the new system. Looks like due to a misconfiguration, several comments have been waiting for moderation for days or weeks. If yours was one of them, please accept my apology - I didn&amp;#39;t have email notifications turned on, so I wasn&amp;#39;t being notified that comments were coming in.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve since fixed the problem, so your comments should show up sooner. Sorry for any confusion!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52316" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category></item><item><title>Better exception reporting in ASP.NET</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/better-exception-reporting-in-asp-net.aspx</link><pubDate>Fri, 01 Aug 2008 21:30:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52314</guid><dc:creator>keith-brown</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52314</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/better-exception-reporting-in-asp-net.aspx#comments</comments><description>&lt;p&gt;In &lt;a href="http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/asp-net-health-monitoring-doesn-t-log-inner-exception-stack-trace.aspx" target="_blank"&gt;my last post&lt;/a&gt;, I commented on how ASP.NET health monitoring doesn&amp;#39;t output stack traces for inner exceptions, which can be problematic due to its heavy reliance on reflection. I spent the morning doing some further spelunking with &lt;a href="http://www.aisto.com/roeder/dotnet/" target="_blank"&gt;reflector&lt;/a&gt;, and my first solution was to implement a custom WebEvent that overrides ToString() to format itself with all of the data I care about. I then overrode the Error event via global.asax and raised my custom event, instead of letting ASP.NET raise its default event. This worked reasonably well with the SimpleMailWebEventProvider, but didn&amp;#39;t seem to change anything at all with the event log provider.&lt;/p&gt;
&lt;p&gt;What I found is that the two providers were using entirely different means to format the events! The email provider calls ToString(bool, bool) on the event to ask it to format itself. But the EventLogWebEventProvider does its own formatting of individual fields of the event. Indeed, its ProcessEvent method has a big list of checks:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (eventRaised &lt;span class="kwrd"&gt;is&lt;/span&gt; WebBaseErrorEvent)&lt;br /&gt;    AddErrorStuff();&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (eventRaised &lt;span class="kwrd"&gt;is&lt;/span&gt; WebAuthenticationSuccessAuditEvent)&lt;br /&gt;    AddLogonStuff();&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;So it seemed like a better approach would be to write my own provider. I left the event log provider alone, and I wrote a custom email provider to display errors in a more useful way. This also allowed me to drop some fields from the event report that aren&amp;#39;t useful for us. And I was able to construct a much more concise and useful subject line (the subject line that SimpleMailWebEventProvider uses is rather clunky since it assumes it might be spitting out a whole bunch of buffered events in one go).&lt;/p&gt;
&lt;p&gt;Not only does my provider include the stack traces for all of the exceptions in the chain, but in the subject line, I display the type of error that is at the root of the problem. So if I am formatting a TargetInvocationException, I drill into its InnerException chain until I find a different exception type, and display that exception type instead.&lt;/p&gt;
&lt;p&gt;Oh, one other benefit of building the custom provider instead of using a custom WebEvent was that I was then able to remove the Error handler from global.asax. All I had to do was replace the SimpleMailWebEventProvider with my own provider, and I got the behavior I wanted. Now my email notifications include detailed stack traces.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ll post the code for this provider once it&amp;#39;s run for a little while in production and I&amp;#39;m satisfied that it works reasonably well.&lt;/p&gt;
&lt;p&gt;UPDATE: I included the code in my &lt;a href="http://www.pluralsight.com/community/blogs/keith/archive/2008/08/04/better-exception-reporting-in-asp-net-part-2.aspx"&gt;third post&lt;/a&gt; in this series.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52314" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>ASP.NET Health Monitoring doesn't log inner exception stack trace</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/asp-net-health-monitoring-doesn-t-log-inner-exception-stack-trace.aspx</link><pubDate>Fri, 01 Aug 2008 17:21:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52306</guid><dc:creator>keith-brown</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52306</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/asp-net-health-monitoring-doesn-t-log-inner-exception-stack-trace.aspx#comments</comments><description>&lt;p&gt;This can be a problem, especially when an ObjectDataSource starts throwing exceptions. The stack trace looks the same because of the way the methods are invoked (via reflection) - you end up with a stack trace for a TargetInvocationException, which basically says, &amp;quot;I used reflection to invoke some method, and it threw an exception. See the inner exception for details.&amp;quot;&lt;/p&gt;
&lt;p&gt;ASP.NET&amp;#39;s health monitoring system does list the inner exceptions (apparently up to a maximum depth of two, from spelunking the code with &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;reflector&lt;/a&gt;), but it does not emit the stack traces for these exceptions, which would be &lt;i&gt;really helpful&lt;/i&gt;. I&amp;#39;ve spent some time this morning trying to figure out how I&amp;#39;d customize things to emit this, and it looks like what I&amp;#39;d have to do is catch the exception and generate a custom WebEvent that overrides ToString(bool, bool) and does everything that WebRequestErrorEvent does, but also generate the inner stack trace.&lt;/p&gt;
&lt;p&gt;That seems a bit ugly. A search for &amp;quot;ASP.NET web event inner exception stack trace&amp;quot; yielded no interesting results, so if you&amp;#39;ve dealt with this and have a cleaner solution, let me know. I&amp;#39;ll post my solution once I get it worked out.&lt;/p&gt;
&lt;p&gt;UPDATE: I ended up &lt;a href="http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/better-exception-reporting-in-asp-net.aspx"&gt;writing a custom email provider&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52306" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Simulating Email in .NET</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/simulating-email-in-net.aspx</link><pubDate>Fri, 01 Aug 2008 16:59:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52305</guid><dc:creator>keith-brown</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52305</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/08/01/simulating-email-in-net.aspx#comments</comments><description>&lt;p&gt;I use email as a notification mechanism a lot, and often in class I&amp;#39;ll demo sending email via a technique that I use frequently when developing code. It allows you to simulate sending an email message.&lt;/p&gt;
&lt;p&gt;The trick to doing this is not to hardcode things like host, port, etc. for your SMTP server when you use System.Net.Mail to send mail. Instead, use the default ctor for &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.aspx" target="_blank"&gt;SmtpClient&lt;/a&gt; as I&amp;#39;ve done in the code below.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="rem"&gt;// note the use of the MailAddress class&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;// this allows me to specify display names as well as email addresses&lt;/span&gt;&lt;br /&gt;    MailAddress from = &lt;span class="kwrd"&gt;new&lt;/span&gt; MailAddress(&lt;span class="str"&gt;&amp;quot;admin@fabrikam.com&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Fabrikam Website&amp;quot;&lt;/span&gt;);&lt;br /&gt;    MailAddress to = &lt;span class="kwrd"&gt;new&lt;/span&gt; MailAddress(&lt;span class="str"&gt;&amp;quot;mari@fabrikam.com&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Mari Joyce&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;    MailMessage msg = &lt;span class="kwrd"&gt;new&lt;/span&gt; MailMessage(from, to);&lt;br /&gt;    msg.Subject  = &lt;span class="str"&gt;&amp;quot;Testing 123&amp;quot;&lt;/span&gt;;&lt;br /&gt;    msg.Body = &lt;span class="str"&gt;&amp;quot;This is only a test!&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span class="rem"&gt;// note use of default ctor&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;// this looks in config to figure out how to send mail&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;new&lt;/span&gt; SmtpClient().Send(msg);&lt;br /&gt;}&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;What you&amp;#39;re telling .NET by using the default ctor for SmtpClient is, &amp;quot;please use my config file to figure out how to send mail&amp;quot;. Now you can use the system.net/mailSettings/smtp section in config to specify the details of your mail server, and all of the code in your app that is written to use the default SmtpClient ctor will inherit these settings. Here&amp;#39;s an example of what the config on a production server might look like (if you put passwords in your config files, be sure to &lt;a href="http://msdn.microsoft.com/en-us/library/ms998283.aspx" target="_blank"&gt;encrypt those sections&lt;/a&gt;): &lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.net&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mailSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;smtp&lt;/span&gt; &lt;span class="attr"&gt;deliveryMethod&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Network&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;network&lt;/span&gt; &lt;span class="attr"&gt;host&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mail.fabrikam.com&amp;quot;&lt;/span&gt;&lt;br /&gt;                 &lt;span class="attr"&gt;port&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;25&amp;quot;&lt;/span&gt;&lt;br /&gt;                 &lt;span class="attr"&gt;userName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;WebsiteMailAccount&amp;quot;&lt;/span&gt;&lt;br /&gt;                 &lt;span class="attr"&gt;password&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;whatever&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;smtp&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;mailSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;system.net&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;During development, I use different settings because I don&amp;#39;t usually want to deal with the hassle of installing an SMTP server on my development box. Instead, I want email messages delivered as individual files in a directory on my hard drive (I always have a c:\mail directory on my development box for just this purpose):&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.net&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mailSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;smtp&lt;/span&gt; &lt;span class="attr"&gt;deliveryMethod&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;SpecifiedPickupDirectory&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;specifiedPickupDirectory&lt;/span&gt; &lt;span class="attr"&gt;pickupDirectoryLocation&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;c:\mail&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;smtp&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;mailSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;system.net&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now when I run the program above, I get a .EML file in my c:\mail directory:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.pluralsight.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/keith/image_5F00_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;margin:0px 0px 0px 35px;border-left:0px;border-bottom:0px;" alt="image" src="http://www.pluralsight.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/keith/image_5F00_thumb.png" width="404" border="0" height="230" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Outlook Express is normally registered as the viewer for .EML files, so double-click the file to view it:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.pluralsight.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/keith/image_5F00_4.png"&gt;&lt;img style="border-right:0px;border-top:0px;margin:0px 0px 0px 35px;border-left:0px;border-bottom:0px;" alt="image" src="http://www.pluralsight.com/community/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/keith/image_5F00_thumb_5F00_1.png" width="292" border="0" height="287" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;If you&amp;#39;ve never seen this method of simulating email before, I hope you find it as useful as I have. Happy coding!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52305" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category></item><item><title>Controlling column width in a GridView</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/07/30/controlling-column-width-in-a-gridview.aspx</link><pubDate>Wed, 30 Jul 2008 17:23:27 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:52286</guid><dc:creator>keith-brown</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=52286</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/07/30/controlling-column-width-in-a-gridview.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve been building some internal pages for our sales team here at &lt;a href="http://www.pluralsight.com/main/" target="_blank"&gt;Pluralsight&lt;/a&gt;, and many of those pages make use of the ASP.NET GridView control to display rectangular data. It&amp;#39;s generally a really easy to use control, but I&amp;#39;ve always struggled with getting column widths to look right.&lt;/p&gt;  &lt;p&gt;My goal is to fix the width of each column at design time, and any field that contains text that may be longer than my fixed width should wrap around, taking up more vertical space in the table. If you are trying to accomplish this goal, you might find these tips helpful.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;1) Set up a CssClass for the GridView itself and include the &lt;a href="http://www.w3.org/TR/REC-CSS2/tables.html#fixed-table-layout" target="_blank"&gt;table-layout:fixed&lt;/a&gt; style. This tells the browser that you&amp;#39;re going to specify the width of each cell. You may also want to include the overall width of the grid here as I mention in (3).&lt;/p&gt;    &lt;p&gt;2) The first row of the table sets the width for each cell, and that&amp;#39;s usually the HEADER row, not the item row, so use either HeaderStyle-CssClass or HeaderStyle-Width to set the width of the cell. I wasted a lot of time trying to set the width using the ItemStyle.&lt;/p&gt;    &lt;p&gt;3) Make certain the table itself is wide enough to hold all of the cells. I added up all of my cell widths and used that to set the width via the CssClass attribute on the GridView.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Using these guidelines, I&amp;#39;m having much better luck controlling the layout of my GridView controls. I hope this simple advise helps someone else!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=52286" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Introducing Microsoft Code Name Zermatt</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/07/09/introducing-microsoft-code-name-zermatt.aspx</link><pubDate>Wed, 09 Jul 2008 20:27:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:51689</guid><dc:creator>keith-brown</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=51689</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/07/09/introducing-microsoft-code-name-zermatt.aspx#comments</comments><description>&lt;p&gt;For a couple of years now, I&amp;#39;ve been giving talks about &amp;quot;claims-based identity&amp;quot;, and &amp;quot;claims-aware applications&amp;quot;. The most concrete example of a claims-based identity architecture that I&amp;#39;ve been able to show so far is Active Directory Federation Services v1 (ADFS) and Windows CardSpace. And the claims programming model I&amp;#39;ve been using is the one that shipped with WCF in the System.IdentityModel assembly.&lt;br /&gt;&lt;br /&gt;But today I&amp;#39;m happy to announce that there&amp;#39;s a new path forward in the claims world. &lt;a href="https://connect.microsoft.com/Downloads/DownloadDetails.aspx?SiteID=642&amp;amp;DownloadID=12937"&gt;Zermatt&lt;/a&gt; is the &amp;quot;identity framework&amp;quot; that I&amp;#39;ve been itching to talk about, but until today, hasn&amp;#39;t been announced publicly.&lt;br /&gt;&lt;br /&gt;Well, &lt;a href="http://blogs.msdn.com/vbertocci/"&gt;Vittorio&lt;/a&gt; just made the &lt;a href="http://blogs.msdn.com/vbertocci/archive/2008/07/09/announcing-the-beta-release-of-zermatt-developer-identity-framework.aspx"&gt;announcement&lt;/a&gt; just a moment ago, and now you can get your hands on this new framework. With it, you can build web applications and services that rely on claims to discover identity details about users. And you can easily build a security token service (STS) that supplies those claims. Zermatt makes this possible by supplying all of the plumbing that implements WS-Trust (for web services) and WS-Federation (for browser-based web applications). All you have to do is figure out what claims you want to issue based on what you know about the user and what you know about the application (aka relying party).&lt;br /&gt;&lt;br /&gt;I was fortunate to be asked by the team to write the &lt;a href="https://connect.microsoft.com/Downloads/DownloadDetails.aspx?SiteID=642&amp;amp;DownloadID=12901"&gt;white paper&lt;/a&gt; introducing Zermatt to developers. You can download it here. The paper introduces the ideas behind claims-based identity, and talks about how you can use Zermatt to centralize authentication (and to some degree, authorization) in an STS, thus making it easy to achieve single sign on in your applications, and even be ready to federate with other organizations or platforms should that need arise.&lt;br /&gt;&lt;br /&gt;Here are some highlights of what you&amp;#39;ll find in Zermatt:&lt;br /&gt;&lt;br /&gt;Zermatt includes a new claims programming model, with IClaimsPrincipal and IClaimsIdentity, two new interfaces that extend the existing IPrincipal and IIdentity that you already know and love from the .NET Framework. IClaimsIdentity adds a collection of claims. Zermatt&amp;#39;s claims programming model is in many ways simpler than that in WCF - the Claim class exposes the value of claims as strings (always) and calls the value of a claim &amp;quot;Value&amp;quot;, instead of &amp;quot;Resource&amp;quot; as WCF did. But the model is also more sophisticated - multi-hop delegation is supported, so one user can &amp;quot;Act As&amp;quot; another user, and the relying party will see the entire chain of delegation as a linked list of IClaimsIdentity objects.&lt;br /&gt;&lt;br /&gt;Zermatt includes an HttpModule that you can wire into your ASP.NET application that will implement WS-Federation for you. This module (called the FAM) is a lot like the &amp;quot;Web Agent&amp;quot; from ADFS, and it makes it quite easy to build a web application that relies on claims.&lt;br /&gt;&lt;br /&gt;Zermatt includes plumbing that sits on top of WCF and simplifies building claims-based web services and clients.&lt;br /&gt;&lt;br /&gt;Zermatt also includes a couple of ASP.NET controls for adding SignIn functionality to websites. The first is a passive sign-in control which simply redirects the browser to an STS to get claims. The second is the highly anticipated InformationCard control that pops the user&amp;#39;s identity selector and lets her choose which identity she wants to use.&lt;br /&gt;&lt;br /&gt;Zermatt comes with a bunch of sample code to help you get started.&lt;br /&gt;&lt;br /&gt;All you need to test-drive Zermatt is Visual Studio 2008 and your curiosity. Download the beta now, read the whitepaper, experiment with the samples, and see what claims-based identity is all about!&lt;br /&gt;&lt;br /&gt;For more on Zermatt, you&amp;#39;ll want to watch &lt;a href="http://blogs.msdn.com/vbertocci/"&gt;Vittorio&amp;#39;s blog&lt;/a&gt;. I&amp;#39;ll also be talking more about it in the future!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=51689" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Security/default.aspx">Security</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Identity/default.aspx">Identity</category></item><item><title>Welcome, David Starr</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/07/09/welcome-david-starr.aspx</link><pubDate>Wed, 09 Jul 2008 13:01:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:51665</guid><dc:creator>keith-brown</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=51665</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/07/09/welcome-david-starr.aspx#comments</comments><description>&lt;p&gt;One of the main reasons that &lt;a href="http://www.pluralsight.com/community/blogs/fritz/default.aspx"&gt;Fritz&lt;/a&gt;, &lt;a href="http://www.pluralsight.com/community/blogs/aaron/default.aspx"&gt;Aaron&lt;/a&gt;, and I wanted to create this company was to provide a home for people who love to teach. We didn&amp;#39;t want to build an empire, and we weren&amp;#39;t out to get rich. We just wanted a place where we could comfortably practice what we love to do: giving software developers a boost - watching that light go on over their heads when a new concept becomes clear. We love to teach, and it&amp;#39;s always exciting to find talented individuals who share that passion.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.pluralsight.com/community/members/david_2D00_starr/default.aspx"&gt;David Starr&lt;/a&gt; is one of those people. I&amp;#39;ve seen him in action, and not only does he have a lot of very practical experience from the trenches, but he also has a clear ability to convey his knowledge and experience to his students. It&amp;#39;s clearly important to David to connect with his students, and he does so in a way that lets them know that it&amp;#39;s all about them - he&amp;#39;s not there just to show off his mad skillz (which he has in abundance!) So I&amp;#39;m very excited to welcome David on board as our newest Pluralsight instructor. I apologize for not writing this sooner - we&amp;#39;ve all been really busy getting the new website out the door.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s what David &lt;a href="http://www.pluralsight.com/community/blogs/starr/archive/2008/07/02/a_2D00_note_2D00_from_2D00_the_2D00_new_2D00_guy.aspx"&gt;had to say&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Welcome!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=51665" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category></item><item><title>Information Card Foundation</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/07/09/information-card-foundation.aspx</link><pubDate>Wed, 09 Jul 2008 12:15:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:51662</guid><dc:creator>keith-brown</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=51662</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/07/09/information-card-foundation.aspx#comments</comments><description>&lt;p&gt;Finally there&amp;#39;s a &lt;a href="http://informationcard.net/"&gt;home on the Internet for information cards&lt;/a&gt;. I&amp;#39;ve been waiting for this for a long time - a place to point consumers, executives, and developers to learn more about information cards. And it&amp;#39;s not just a Microsoft thing. &lt;a href="http://informationcard.net/members"&gt;Founding members&lt;/a&gt; include Google, PayPal, Novell, and the Liberty Alliance. While the adoption of information cards has been happening at a snail&amp;#39;s pace, this collaboration might just change that.&lt;/p&gt;
&lt;p&gt;And that would be very good for consumers.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=51662" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Security/default.aspx">Security</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Identity/default.aspx">Identity</category></item><item><title>Demos from my TechEd talks</title><link>http://www.pluralsight.com/community/blogs/keith/archive/2008/06/04/51105.aspx</link><pubDate>Wed, 04 Jun 2008 13:10:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:51105</guid><dc:creator>keith-brown</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight.com/community/blogs/keith/rsscomments.aspx?PostID=51105</wfw:commentRss><comments>http://www.pluralsight.com/community/blogs/keith/archive/2008/06/04/51105.aspx#comments</comments><description>&lt;P&gt;To those who came to my talks at &lt;A href="http://www.microsoft.com/events/teched2008/developer/default.mspx"&gt;TechEd 2008 Developers&lt;/A&gt;, thank you! Be sure to fill out an evaluation before you leave; scores matter a lot to the conference organizers, so let them know what you thought.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.pluralsight.com/keith/presentations/TimeTracker.zip"&gt;Here is the code&lt;/A&gt; from my ADFS talk.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.pluralsight.com/keith/presentations/ClaimsDemos.zip"&gt;Here&amp;nbsp;is the code&lt;/A&gt; from my&amp;nbsp;Understanding Claims talk.&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight.com/community/aggbug.aspx?PostID=51105" width="1" height="1"&gt;</description><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Security/default.aspx">Security</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Geek+talk/default.aspx">Geek talk</category><category domain="http://www.pluralsight.com/community/blogs/keith/archive/tags/Identity/default.aspx">Identity</category></item></channel></rss>