Thursday, 29 January 2009

Sorting and De-duping arrays

I seem to be obsessed with sorting based on the number of posts I've made on the topic.
Sorting a simple string[] is easy using:

string[] recordIds = { "q", "z", "a", "b", "q" };

To stop a third party component from failing we had to ensure that our string[] array contained only unique strings. Sorting and de-duping using LINQ could be done in a single line:

string[] recordIds = { "q", "z", "a", "b", "q" };
var sortedUniqueIds = (from id in recordIds orderby id select id).Distinct();
int i=0;
foreach (string id in sortedUniqueIds)
   recordIds[i++] = id;

Microsoft have an excellent LINQ samples page: 101 LINQ Samples

Wednesday, 28 January 2009

Unhandled Exceptions in VS2008

In our solution we have two basic projects: Client and Server, communicating via WCF.

When the Server components throw an exception the Server's WCF layer catches it, wraps it up as a FaultException and rethrows for the Client to catch.

Even though the exception is handled the debugger signals an unhandled exception when running the Server though VS2008.

From the Debug | Exceptions menu option I've turned the exception handling off for that one specific type: System.ServiceModel.FaultException`1

It would appear that disabling this exception affects only the Server project.

Tuesday, 27 January 2009

Sorting Generic Collections - Redux

Using LINQ it turns out to be quite easy to sort a generic Dictionary by either Key or Value.

In these examples a list of sorted keys is returned in the 'keys' variable.

Alternately the LINQ statement can used directly in a foreach loop.

Dictionary<string, string> dict = new Dictionary<string, string>();

// Sort by Key
var keys = from key in dict.Keys orderby key ascending select key;

// Sort by Value
var keys = from key in dict.Keys orderby dict[key] ascending select key;

// Sort within foreach(...) by Key
foreach(string aKey in (from key in dict.Keys orderby key ascending select key)){

Thursday, 22 January 2009

WCF Security and Certificates

It turns out, you can't do Message level authentication without a Certificate involved to identify the server as the server..
and then because I don't have a bona-fide bought and paid for Certificate for my server, it still fails with arcane errors until you add a magic line to the config file on the client saying "trust any old certificate -- we're not fussy!"
On the server config, I needed this line :
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
so I'll need to tweak those values somehow and right now on the client to avoid the "trusted certificate" issue, I needed :
Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
is in the user's Trusted People store, then it will be trusted without performing a
validation of the certificate's issuer chain. This setting is used here for convenience so that the
sample can be run without having to have certificates issued by a certificate authority (CA).
This setting is less secure than the default, ChainTrust. The security implications of this
setting should be carefully considered before using PeerOrChainTrust in production code.
<authentication certificateValidationMode="PeerOrChainTrust" />
Certificate Validation Differences Between HTTPS, SSL over TCP, and SOAP Security
You can use certificates in Windows Communication Foundation (WCF) with message-layer (SOAP) security in addition to transport-layer security (TLS) over HTTP (HTTPS) or TCP. This topic describes differences in the way such certificates are validated.
When using HTTPS to communicate between a client and a service, the certificate that the server authenticates with must support chain trust by default. That is, it must chain to a trusted root certificate authority. No online check is performed to see whether the certificate has been revoked. You can override this behavior by registering a RemoteCertificateValidationCallback callback, as shown in the following code:
ServicePointManager.ServerCertificateValidationCallback +=
new RemoteCertificateValidationCallback(ValidateServerCertificate);
where the signature for ValidateServerCertificate is as follows:
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)