Serializing a DataContract class to an XML string

Sometimes during development I want to have a light-weight approach to logging request and response messages without setting up WCF tracing.​ Regardless of how I am logging (Trace, EntLib, whatever), I need to get a printable version of the data message.

I always recommend treating DataContract classes strictly as data transfer objects (DTO), that is they exist purely for describing the shape of the message on the wire. That means I don’t add any fancy constructors or business logic of any kind to the DTOs. This maintains a separation of concerns. However, all CLR types do have a ToString method, so I an fine with putting it to better use than telling me the name of the type.

In the sample code, CreateSecretRequest overrides ToString using a static helper method, Helper.ToXmlString. That helper method wraps an XmlSerializer and a StringWriter together to serialize the DTO to a string of XML that I can log. All DataContract classes can use the same ToXmlString method to implement their override of ToString in a simple one-liner.

using System.IO;
using System.Xml.Serialization; 

public static class Helper
{
  public static string ToXmlString( object value, string defaultNamespace )
  {
    var writer = new StringWriter();
    (new XmlSerializer( value.GetType(), defaultNamespace )).Serialize( writer, value );
    return writer.ToString();
  }
} 

// a sample data transfer object

using System.Runtime.Serialization; 

[DataContract( Namespace = XmlNamespaces.Secret.CreateSecretRequest )]
public class CreateSecretRequest
{
  [DataMember]
  public string Name { get; set; } 

  [DataMember]
  public string Description { get; set; } 

  public override string ToString()
  { return Helper.ToXmlString( this, XmlNamespaces.Secret.CreateSecretRequest ); }
}

Be careful! This is not the same XML that the service sent or received on the wire. Use WCF Tracing to see what is really happening with your services. This is nearly a 100% genuine approximation of the message, suitable for some quick-and-dirty logging or debugging diagnostics.

Get your current WindowsIdentity name and groups

Are you having a little identity crisis? Not sure who you really are in a given environment? Or what groups you belong to? Find out for real, for sure. Get the name of the current WindowsIdentity (Windows user) and the groups to which the user belongs.

using System;
using System.Text;
using ssp = System.Security.Principal;

var user = ssp.WindowsIdentity.GetCurrent();
var name = user.Name;

var groups = new StringBuilder();
foreach ( var group in user.Groups )
  groups.AppendLine( group.Translate( typeof( ssp.NTAccount ) ).ToString() );

var message = string.Format( "Name: {0}\nGroups: {1}", name, groups.ToString() );

This nugget of code has saved me at least three times when I was convinced that I was someone else or in some other role/group than I really was.

Upsert performs update or insert

The SQL MERGE statement, introduced in SQL-92, is the best way to update columns in a table if the the row exists, or insert a new row if the row does not exist. This is performed in a single T-SQL statement.

The source code below updates or inserts values into a Prices table that has a Name and Price column.

CREATE PROCEDURE [dbo].[UpsertPrice]
(
  @name nvarchar(MAX),
  @price decimal(18, 2)
)
AS
BEGIN
  SET NOCOUNT ON; 

  MERGE Prices AS target
  USING (SELECT @name, @price) AS source (Name, Price)
  ON (target.Name = source.Name)
  WHEN MATCHED THEN
    UPDATE SET target.Price = source.Price
  WHEN NOT MATCHED THEN
    INSERT (Name, Price)
    VALUES (source.Name, source.Price);
END;

This combination of update-or-insert values is known by the portmanteau ‘upsert’. I read it on the Internet so it must be true.

How to demo and test sending email

Making your application send email is a pretty common requirement. But without setting up your very own development SMTP server to actually send that email, how can you demonstrate that capability to the stakeholder or test that it works?

The sample below shows how to send email locally on your workstation. The email will appear as a .eml file in a specified folder. Double-click on the .eml file and it will open in Outlook.

using System.Net.Mail;

namespace SmtpDemo
{
  class Program
  {
    static void Main( string[] args )
    {
      // Note: In .NET 4.0, System.Net.Mail.SmtpClient implements IDisposable;
      // .NET 3.5 and earlier it does not.
      using ( var smtpClient =
                  new SmtpClient( "localhost" )
                  {
                    DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory,
                    PickupDirectoryLocation = @"C:\Users\visualstuart\Desktop"
                  } )
      {
        string from = "<a href="mailto:support@visualstuart.net">support@visualstuart.net</a>";
        string to   = "<a href="mailto:pipi@visualstuart.net">pipi@visualstuart.net</a>";
        string subject = Your request has been received";
        string body = "We got your request. Hang in there, help is on the way.";

        smtpClient.Send( from, to, subject, body );
      }
    }
  }
}

The interesting bits are in the instantiation of the SmtpClient object. Also note the comment on SmptClient implementing IDisposable in .NET 4.0, but not in earlier versions of the framework. Since I am targeted the .NET 4.0 framework, I’ve treated that instantiation as resource acquisition and enclosed it in a using statement. 

This sample uses no configuration. Alternatively, you can configure these values in the <smtp> element of app.config.

Reversing something that doesn’t belong to you

I was working on an implementation of a REST service recently, making it respond to the HTTP Accept headers on the incoming request. As you can see from the HTTP/1.1 specification, Accept request-headers should be honored in the order that they’re listed. So it was absolutely awesome to learn that

using System.ServiceModel.Web;

var acceptHeaders = WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements();
foreach ( var acceptHeader in acceptHeaders )
{
  // process acceptHeader...
}

processes the headers in the opposite order in which they are specified in the request. And that’s not awesome in a good sense.

The IncomingWebRequestContext.GetAcceptHeaderElements method returns a System.Collections.ObjectModel.Collection<T> and that is not a class I own or can change. But still I’d like an iterator for Collection<T> that yields up its elements in reverse order so that I can still use the foreach syntax. Since Collection<T> is not a class I can modify, extension methods come to mind. Here’s an extension method for an iterator on Collection<T> that does the trick.

using System.Collections.Generic;
using System.Collections.ObjectModel;

public static class Extensions
{
  public static IEnumerable<T> Reverse<T>( this Collection<T> collection )
  {
    for ( int i = collection.Count - 1; i >= 0; --i )
      yield return collection[ i ];
  }
}

Now I can write the foreach loop to use the extension method.

foreach ( var acceptHeader in acceptHeaders.Reverse() )
{
  // process acceptHeader in the correct order...
}

I am still dumbfounded that GetAcceptHeaderElements reverses the order of the elements (why would that ever be good?) but a few lines sends me on my way without cluttering up the code.

Or you could look it up

I look at a lot of code. Code that was written a long time ago and those coders have long since left the building. Code that someone once cut their C# teeth on. Code that only its mother could love.

A common shortcoming is writing out what should be a table look up with flow control logic. Here’s an example of what I mean.

enum AccountType { Retail, Wholesale, Nonprofit }

private static decimal GetDiscountUsingIf( AccountType type )
{
  if ( type == AccountType.Wholesale )
    return 0.2M;
  else if ( type == AccountType.Nonprofit )
    return 0.1M;
  else if ( type == AccountType.Retail )
    return 0.0M;

  return 0.0M;
}

There’s no joy in this code. If the enumeration is prone to change over time, support and maintenance of this style of code quickly becomes error prone. And why is there a default return value at the end of the GetDiscountUsingIf method? Is it a hedge against additional values being added to the enumerations?

Only slightly better would be to convert if/else-if structure to a switch statement.

private static decimal GetDiscountUsingSwitch( AccountType type )
{
  switch ( type )
  {
    case AccountType.Wholesale:
      return 0.2M;
    case AccountType.Nonprofit:
      return 0.1M;
    case AccountType.Retail:
      return 0.0M;
    default:
      return 0.0M;
  }
}

This time the reason for having a default clause is that without it the compiler will warn that not all code paths return a value. Switch statements are cumbersome (e.g., with the potential for fall-throughs, etc.), the performance isn’t great (average number of comparisons is N/2, and worst case in N comparisons), and I think switch statements in general tend to be overused. So every time you see a switch statement I encourage you to think hard if it can be replaced. In this case, it is easily replaced with a Dictionary from the System.Collections.Generic namespace.

using System.Collections.Generic;

private static readonly Dictionary<AccountType, decimal> discounts =
  new Dictionary<AccountType, decimal>
  {
    { AccountType.Wholesale, 0.2M },
    { AccountType.Nonprofit, 0.1M },
    { AccountType.Retail, 0.0M }
  };

private static decimal GetDiscountUsingDictionary( AccountType type )
{
  if ( discounts.ContainsKey( type ) )
    return discounts[ type ];
  throw new ArgumentOutOfRangeException( "type" );
}

The discounts dictionary structure separates the relationship of the keys and values from the lookup logic. The indexer property, discounts[ type ], does most of the lookup logic, and at O(1) it is more efficient than the O(N) linear search approach of the previous two solutions. With the key-value association and lookup work taken care of with pretty terse syntax, the code is simple enough that I can contemplate what should be done with an AccountType key that’s not in the table, in this case throwing an exception that the argument is out of range.

So the next time you’re got a job that is essentially a dictionary look up, use a Dictionary to look it up.