.NET Dictionary with Case-Insensitive Comparison

How do you create a IDictionary that does case-insensitive key matches. There are a number of solutions posted on the web, but none of them seem quite correct. The following should work.

IDictionary map = new Dictionary(new StringCompInsensitive());

where

public class StringCompInsensitive : IEqualityComparer
{
    public bool Equals(string x, string y)
    {
         return String.Compare(x, y, true) == 0;
    }

    public int GetHashCode(string obj)
    {
          return ((string)obj).ToLower().GetHashCode();
    }
}

Application Configuration Error Converting to .NET Framwork 2.0

I converted an old console app from .NET Framework 1.1 to 2.0 using Visual Studio 2008. When I ran it I got the following helpful error message

This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.

Looking in the Security Event Log I found the following messages:

Generate Activation Context failed for C:\ParsII\bin\server\CCSWinService2.exe. Reference error message: The operation completed successfully.

Syntax error in manifest or policy file “C:\ParsII\bin\server\CCSWinService2.exe.Config” on line 1.

The last one was the key. In the app config file the first line was

<?xml version="1.0" encoding="Windows-1252"?>

That should be perfectly legal for an XML file, but deleting it caused everything to work perfectly.

Configuring IIS for HTTP GET

I recently ran into some frustrating problems doing something that ought to be really simple: setting up a directory on IIS so that the files could be downloaded with a HTTP GET. Some files would work fine; others would get a 404 error (NOT FOUND).

Here’s a checklist of possible configuration problems:

  • Right-click on the top IIS Manager node, select Properties and press the MIME Types button. Make sure a MIME type is defined for the file extension.
  • Click the Web Service Extensions node and make sure there is no web service extension defined for that particular file type. If there is IIS will try to pass the file to it rather than download the file.
  • If the file is executable (.dll, .exe, etc.) bring up Properties for the web application, select the Home Directory tab and make sure Execute Permissions is set to “Scripts only”. (NOT to “Scripts and Executables”.)

Server Configuration Problems with WCF

If you have started developing web services with Windows Communication Framework (WCF) you will no doubt have noticed that it is cleaner and more powerful than the old ASP.NET framework. However there are some hidden pitfalls. In particular WCF is a lot more finicky about how the web server is configured. If you aren’t careful this can cause code

that works in your test environment to mysteriously fail when moved to production. Here are some pointers on how to avoid these problems.
Continue reading

Handling XML dateTime fields in .NET

The XML xs:dateTime format specifies that the date and time must be passed in ISO 8601 format. Also you will probably want to pass it in a time zone-independed way. The easiest way to do this is to covert the date to UTC (a.k.a. Greenwich Mean Time or “Zulu”). This can be done as follows:

public const string ISO_UTC_FORMAT = "yyyy-MM-ddTHH:mm:ss.sZ";
DateTime date;
XmlWriter w;
String s = date.ToUniversalTime().ToString(ISO_UTC_FORMAT);
w.WriteString(s);

The other thing to be careful about is never to use XmlReader.ReadElementStringAsDateTime() to read this data. At least in Framework 3.0 (an probably earlier) it will IGNORE THE TIME ZONE INDICATOR. Instead use

XmlReader r;
DateTime dt = DateTime.Parse(r.ReadElementString());

The standard DateTime.Parse() handles the ISO format correctly.

.NET => COM Invalid Cast Exception

If you get an InvalidCastException when accessing a COM object from .NET, it generally means that there is a version mismatch between the .NET interop dll and the COM object.

  1. Use Lutz Net Reflector to open the interop dll and disassemble the definition of the interface that you are trying to cast to. Note the interface ID (GUID).
  2. Use OLE Viewer to open the COM dll as a type library. Examine the interface definition to make sure the GUID is the same.
  3. If using DCOM/COM+, run Component Manager, open the component, open the interface list, right-click on the interface and select Properties. Once again the GUID should match.

If everything checks out, make sure that the COM interface is actually registered on your machine. Using an unregistered interface produces the same error message as using the wrong version. Note that if you are using DCOM remoting you do not need to have the component dll registered on the client machine, but you must register the dll that defines the interface that you are using. Just having the interop is not enough.

This is fairly obvious stuff once you figure it out, but it just took me several hours to track it down.