2010
09.11

Eric Lippert has put a little problem up on his blog – Old school tree display; here’s how I got to a solution.

First, examine the desired output:

a
├─b
│ ├─c
│ │ └─d
│ └─e
│   └─f
└─g
  ├─h
  │ └─i
  └─j

We’re going to be doing a depth-first tree traversal. Recursion seems like the easiest way to go. We need to return a string – building up a string like this naturally suggests a StringBuilder. Just to confirm I can remember back to dealing with trees at university, first just print out the traversal:

public static string Dump(Node root)
{
   StringBuilder nodeDump = new StringBuilder();
   Dump(root, nodeDump);

   return nodeDump.ToString();
}

private static void Dump(Node node, StringBuilder nodeDump)
{
   nodeDump.AppendLine(node.Text);
   foreach(var child in node.Children)
   {
      Dump(child, nodeDump);
   }
}

Phew, I haven’t forgotten everything, we get the right output:

a
b
c
d
e
f
g
h
i
j

So all that’s missing are the tree lines. This first pass has got the first line correct though, so there’s no need to change that. Some “stuff” needs adding to the loop. The first thing I notice is that the last child of a node is preceded by a └, whereas the other children are preceded by a ├. So we need to test whether we’re dealing with the last child. This is going to be easier to do with a plain old for loop rather than using foreach.

So, let’s see if I can get the correct symbol to be printed before each node:

private static void Dump(Node node, StringBuilder nodeDump)
{
   nodeDump.AppendLine(node.Text);
   for(int i = 0; i < node.Children.Count; i++)
   {
      if(i + 1 == node.Children.Count)
      {
         nodeDump.Append('└');
      }
      else
      {
         nodeDump.Append('├');
      }
      
      nodeDump.Append('─');
      
      Dump(node.Children[i], nodeDump);
   }
}

This gives

a
├─b
├─c
└─d
└─e
└─f
└─g
├─h
└─i
└─j

Ok, so now all that’s missing are the spaces and vertical lines. This needs to be done before appending the lines we’ve already got. Thanks to the magic of recursion, we only need to care about the prefix text for the current node in the loop.

If we’re dumping the last child, it’ll be prefixed by two spaces. If not, it’ll be prefixed by a │ and a space. This will be in addition to whatever prefix is passed into the method. This means the Dump method needs to take another paramter, prefix. For the root node this is going to be the empty string.

At the same time, the test for the last child is a bit ugly. As we now need to know if we’ve got the last child in two places, this if/else can be collapsed into a bool variable, and the tests can use the conditional operator, which will be much neater.

public static string Dump(Node root)
{
   StringBuilder nodeDump = new StringBuilder();
   Dump(root, nodeDump, String.Empty);
   
   return nodeDump.ToString();
}

private static void Dump(Node node, StringBuilder nodeDump, string prefix)
{
   nodeDump.AppendLine(node.Text);
   for(int i = 0; i < node.Children.Count; i++)
   {
      bool isLastChild = i + 1 == node.Children.Count;
      nodeDump.Append(prefix);
      nodeDump.Append(isLastChild ? '└' : '├');
      nodeDump.Append('─');
      
      Dump(node.Children[i], nodeDump, prefix + (isLastChild ? "  " : "│ "));
   }
}

It works!

a
├─b
│ ├─c
│ │ └─d
│ └─e
│   └─f
└─g
  ├─h
  │ └─i
  └─j
2010
03.16

Once you’ve used svcutil to create proxy classes for a service (or created a Service Reference in Visual Studio), it’s often a bit of a pain to write the wrapper code that needs to instantiate the client, call the service operation, and close or abort the client as appropriate. So I wrote a generic ServiceClient class which will hopefully help to eliminate some boiler-plate code – it’s shown below.

/// <summary>
/// A WCF service client.
/// </summary>
/// <typeparam name="TContract">The type of the service contract.</typeparam>
internal class ServiceClient<TContract> : IDisposable
	where TContract : class
{
	/// <summary>
	/// The service client object.
	/// </summary>
	private TContract client;

	/// <summary>
	/// Initializes a new instance of the ServiceClient class.
	/// </summary>
	/// <param name="endpointName">The name of the endpoint to use.</param>
	public ServiceClient(string endpointName)
	{
		ChannelFactory<TContract> f = new ChannelFactory<TContract>(endpointName);
		this.client = f.CreateChannel();            
	}

	/// <summary>
	/// Calls an operation on the service.
	/// </summary>
	/// <typeparam name="TResult">The type of the object returned by the service operation.</typeparam>
	/// <param name="operation">The operation to call.</param>
	/// <returns>The results of the service operation.</returns>
	public TResult ServiceOperation<TResult>(Func<TContract, TResult> operation)
	{
		return operation(this.client);
	}

	/// <summary>
	/// Calls an operation on the service.
	/// </summary>
	/// <param name="operation">The operation to call.</param>
	public void ServiceOperation(Action<TContract> operation)
	{
		operation(this.client);
	}

	/// <summary>
	/// Disposes this object.
	/// </summary>
	public void Dispose()
	{
		try
		{
			if (this.client != null)
			{
				IClientChannel channel = this.client as IClientChannel;
				if (channel.State == CommunicationState.Faulted)
				{
					channel.Abort();
				}
				else
				{
					channel.Close();
				}
			}
		}
		finally
		{
			this.client = null;
			GC.SuppressFinalize(this);
		}
	}
}

With this class, you can call an operation SaveEmployee on a service with an IEmployeeService interface like this:

using (var client = new ServiceClient<IEmployeeService>("EmployeeEndpoint"))
{
	var response = client.ServiceOperation<EmployeeResponse>(
		c => c.SaveEmployee(request));
}

Wrapping the call in a using block means the client object is correctly closed and disposed, using the IDisposable interface. And if you’re calling an operation that doesn’t return anything, you can use the overload of ServiceOperation that takes in an Action.

2010
03.10

A common task when consuming a WCF service is translating your business objects into the proxy objects used in a service operation call. As an example, say you’ve got a Person class, and you’re calling a WCF service operation called SaveEmployee(). When creating a reference to this service, the svcutil program will have created some proxy classes. To call the SaveEmployee() operation, you’ll need to translate your local Person object into the proxy object. Extension methods provide a nice clear way of doing this.

So, the local Person business class will be something like this:

public class Person
{
    public string Forename { get; set; }

    public string Surname { get; set; }

    public int Age { get; set; }
}

We want to call a WCF service called EmployeeService, which has an operation SaveEmployee(). This operation takes a person to save as a parameter. The type of this parameter is Employee, which svcutil has created for us in the service proxy. This may look something like this:

internal partial class Employee : 
    object, System.Runtime.Serialization.IExtensibleDataObject
{
    private string FirstNameField;
    private string LastNameField;
    private int AgeField;

    [System.Runtime.Serialization.DataMemeberAttribute()]
    internal string FirstName
    {
        get { return this.FirstNameField; }
        set { this.FirstNameField = value; }
    }

    [System.Runtime.Serialization.DataMemeberAttribute()]
    internal string LastName
    {
        get { return this.LastNameField; }
        set { this.LastNameField = value; }
    }

    [System.Runtime.Serialization.DataMemeberAttribute()]
    internal int Age
    {
        get { return this.AgeField; }
        set { this.AgeField = value; }
    }
}

As the service operation SaveEmployee needs an Employee and we have a Person, we need to translate from the latter to the former. An extension object can do this for us nicely:

internal static class PersonTranslator
{
    public static Employee TranslateToEmployee(this Person person)
    {
        return new Employee()
        {
            FirstName = person.Forename,
            LastName = person.Surname,
            Age = person.Age
        };
    }
}

Now the call to the service operation is nice and clear:

public SaveEmployee(Person person)
{
    var client = new EmployeeServiceClient();
    client.SaveEmployee(person.TranslateToEmployee());
    client.Close();
}
2010
01.28

In a previous post I explained how to configure Impersonation and Delegation in ASP.Net (for the Windows Server 2008 and IIS7 case at least). Turns out there’s one extra little step required.

After all that setup, I could use Internet Explorer to browse to the site fine – integrated Windows Authentication would let me in. However, as the DNS had yet to be set up, and the web server and the website had the same IP address, I was browsing using the machine name, e.g. http://machine.domain/website instead of http://dnsname.co.uk/website.

When the DNS was set up and I tried to browse to the website, I got a Windows user name & password box popping up. After 3 tries I was denied access (a 401 error). Just changing the DNS name to the machine name in the location bar let me in, even though they were both the same IP address!

Using Fiddler, I could see the initial client GET request, and the server’s 401 challenge response, including a WWW-Authenticate header set to “Negotiate”. This occurred in both cases (browsing to the DNS name and to the machine name). However, the client response to this challenge was different in each case. The Negotiate token the client sent to the DNS name was much shorter than the one sent to the machine name. Clearly something was telling the client not to send the proper Kerberos authentication token to the DNS name.

Just looking at the HTTP traffic was not enough here – for cases like these a lower-level tool like Microsoft’s Network Monitor is required, or Wireshark if you’re feeling hardcore. This showed that the client was encountering a Kerberos error. A bit of searching around this and…

A magic SPN setting will solve this, all explained in a handy MSDN article. You will need to run this command (I ran it on the web server itself, however this may not be necessary):

setspn -A HTTP/[dns name of the site] [machine name]

Then a reboot of the web server, and a few hours’ wait for the settings to propagate around the domain. This will allow clients to send complete Kerberos authentication tokens to the website. Problem solved!

2010
01.22

I was trying to set up a WCF net-tcp service on a test environment, but kept getting an error saying the certificate could not be found. The problem was down to a slight difference between the test certificates we were using locally, and the certificate we were given for the test environment. We’re using FindBySubjectDistinguishedName in the config.

The test certificate’s subject looked like this:

CN = TestCertName

Whereas the environment certificate’s subject looked like:

CN = CertName
OU = Company Ltd.
O = Company
L = Town
S = County
C = Country Code

All the examples I’ve seen just cover certificates with the CN part. This is straightforward to reference in the WCF config:

<serviceCredentials>
   <serviceCertificate
            storeLocation="LocalMachine"
            storeName="My"
            findValue="CN=TestCertName"
            x509FindType="FindBySubjectDistinguishedName" />
</serviceCredentials>

However, when the certificate subject has multiple parts (i.e. more than just CN), you need to put all of them in the findValue attribute. But how to separate them? I tried several characters – space, comma, semicolon, colon – none worked. The certificate could not be found! Finally I noticed that in the top part of the certificate’s properties window, the values are separated by a comma and a space. Unbelievably, this also applies to the config! How intuitive. So for the “CertName” certificate above, here’s how to reference it in the WCF config:

<serviceCredentials>
   <serviceCertificate
            storeLocation="LocalMachine"
            storeName="My"
            findValue="CN=TestCertName, OU=Company Ltd., O=Company, L=Town, S=County, C=Country Code"
            x509FindType="FindBySubjectDistinguishedName" />
</serviceCredentials>
2010
01.21

ASP.Net exposes a handy Windows feature called Impersonation. This lets an application access local resources using the credentials of the current user. Local resources is important – if you want to access some files, then that’s fine, but if you want to access a remote database, you’re going to need Delegation as well.

It’s fairly simple to set this up once you know what needs doing. Getting to that stage wasn’t the most fun I’ve ever had – the MSDN articles on the subject are useful, but they seem to want to cover at least 3 topics at a time, which can be a little confusing.

The scenario was this: an intranet web application would authenticate users using Windows Authentication, granting access based on their Active Directory roles. The application would access the back-end SQL Server database using Integrated Security, with the credentials of the current user. This gives two main advantages – you don’t have to setup or administer a separate account or accounts for the database, and auditing via SQL triggers is easy. However, this approach is only really suited to an intranet scenario, as database connection pools are used on a per-user basis. Too many users and the database will not be happy.

The setup is in four parts.

ASP.Net

Under the <system.web> section of your web.config, add the following:

<authentication mode="Windows"/>
<identity impersonate="true"/>

Also, make sure you’re using a connection string that uses Integrated Security.

IIS

I’m using IIS7, which has some more detailed settings than IIS6. In the website or virtual directory, ensure that Anonymous Authentication and Forms Authentication are disabled, and ASP.Net Impersonation and Windows Authentication are enabled. IIS should pick this up from web.config.

IIS Authentication section

IIS7 lets you specify “providers” for Windows Authentication. You must use the Negotiate:Kerberos provider. Choosing this provider will mean that “Kernel-mode authentication” cannot be used. This is disabled under the Advanced Settings within the Authentication section.

Active Directory

The web server’s Active Directory properties must be edited to enable Delegation of credentials onto the SQL server. There’s a great explanation with a screen grab of the Active Directory property page in a post from Ken Schaefer.

Windows Server 2003 domains and later support Constrained Delegation, which can constrain the delegation to a specific service on the target machine. This is obviously more secure. To delegate to SQL Server, MSSQLSvc is the service you need.

SQL Server

All you need to do at the database level is grant the relevant permissions for the users or roles you want accessing the database.

Now it should all magically work!

UPDATE: That might not be all! See Part 2.

2010
01.21

The recent attacks against Google from somewhere in China have brought significant mainstream media attention on the security deficiencies of Microsoft’s Internet Explorer, particularly the much-hated IE6. Whilst IE6 seems to have been the culprit in this case, the French, German and Australian governments have all issued warnings to all their citizens, suggesting they stop using Internet Explorer altogether, no matter what version. This has lead to sharp increases in downloads of Firefox and Opera. Meanwhile, Microsoft is issuing an emergency patch for IE, apparently due out today.

IE6 usage is from two places. The first culprits are companies who enforce its use because they need it to run their legacy intranet applications. The second are people with old versions of Windows who have no idea about browsers or automatic updates.

The latter group will never learn – they bought Windows before Microsoft enabled automatic updates by default, and they’re only going to stop using IE6 when their machine haemorrhages its last under a mountain of viruses and malware.

But maybe the IE6-loving companies will look a bit harder at their choice of browser with the current furore. The UK government has already warned its departments that using IE6 might not be such a great idea. Companies may also have to consider upgrading to Windows 7 in a few years, and there’ll be no IE6 there, not without some crazy hacking around anyway.

The fact that mainstream media is bringing the security failures of IE6 to the masses is great news. Channel 4 News specifically mentioned IE6 last night. Hopefully this is going to filter down to some suits and persuade them it’s worth upgrading their legacy intranet web applications.

It won’t be too long before all the crazy IE6 hacks and workarounds currently needed in mainstream-targeted websites are a thing of the past. Hurrah!

2009
11.16

A while ago, I realised I had iTunes installed on my work computer. I didn’t want any extraneous services running, so off it went. A few days later I realised I no longer had a DVD drive in My Computer.

Device Manager said there was a problem with the drivers, but no new ones could be found automatically, and rolling back didn’t work as they hadn’t actually changed. An interweb search for drivers turned up nothing. There were no physical connection issues, all looked fine.

After a while I investigated the Event Log and saw the following error occurred in the System log every boot-up:

The following boot-start or system-start driver(s) failed to load:
Imapi
redbook

I searched again with this info, and stumbled across a handy Microsoft article, “Your CD drive or DVD drive is missing or is not recognized by Windows or other programs”. This pointed me to some obscure registry key to do with CD burning, and a value called “UpperFilters”. This contained two values, “Sidney” and “GEARAspiWDM”. I deleted the value then restarted, and the DVD drive was back!

I checked the registry again, and the “UpperFilters” value was back, but “GEARAspiWDM” was not. It turns out that this is some kind of burning driver that was probably installed by iTunes, but not removed from the registry during the uninstall. Thanks Apple! iTunes can still be a pain after death.

2009
11.06

A system at work stores big object graphs in the database as varbinary(MAX). To do this, the BinaryFormatter class is used. When my new version of the system was installed, the objects would be retrieved out of the database as normal, but after deserialization, they were empty – all properties had default values (i.e. null for reference types, 0 for ints, etc). This was a bit of mystery, as no exceptions were being thrown, and all I thought I’d done was add a new property to the bottom of one of the classes.

I realised I’d also employed my anal side to change the names of the private backing fields for the properties. Might as well try out the code plugin here, so… I changed this:

private int SomePropertyField;

public int SomeProperty {
   get { return SomePropertyField; }
   set { SomePropertyField = value; }
}

to this:

private int someProperty;

public int SomeProperty {
   get { return someProperty; }
   set { someProperty = value; }
}

I was under the mad impression that changing private fields was ok. Not so when using binary serialization – the entire oject graph is serialized, including both public and private members.

If you’re going to use binary serialization, it’s probably wise to prevent any private fields from being serialized, like so:

[NonSerialized]
private int someProperty;

If this wasn’t considered though, it’s too late. It seems like using binary serialization is painting yourself into a corner. Once you’re saving and retrieving binary, it’s difficult to change the format, apart from adding fields or changing enumerations. Adding the [NonSerializable] attribute after you’ve started saving stuff away will break compatibility, so you’re pretty stuck. This seems to destroy the whole concept of using public properties with private backing fields – you’re supposed to be able to keep a consistent public interface whilst maintaining control over the internal implementation.

From my brief foray into the world of binary serialization, I’d say it’s best to thoroughly plan out exactly what you need to be serialized, or it will be too late to change anything. Either that or don’t bother and save a big headache.

2009
10.22

It Begins

Well, here we go. My blog starts now. Hopefully this will be interesting…