Easing logical OR and logical AND comparison in C#

How often have seen or written comparison code like this?

    public bool IsSupportedImage(string extension)
    {
        return (extension == "jpg" || extension == "jpeg" || extension == "png" || extension == "bmp");
    }

Every developer should answer with “yes” because logical OR and logical AND comparison is one of the basic concepts of programming. What I don´t “like” in this statement is the redundance of the parameter extension.

So I wrote some extension methods that I really use in every project at Tekaris.

    public static class ObjectExtensions
    {
        public static bool IsOneOf<T>(this T instance, params T[] these)
        {
            return these.Contains(instance);
        }

        public static bool IsOneOf<T>(this T instance, IEnumerable<T> these)
        {
            return !IsNoneOf(instance, these.ToArray());
        }

        public static bool IsNoneOf<T>(this T instance, params T[] these)
        {
            return !IsOneOf(instance, these);
        }

        public static bool IsNoneOf<T>(this T instance, IEnumerable<T> these)
        {
            return IsNoneOf(instance, these.ToArray());
        }
    }

The same comparison can be done this way:

    public bool IsSupportedImage(string extension)
    {
        return extension.IsOneOf("jpg", "jpeg", "png", "bmp");
    }

And a short example for IsNoneOf

    public static bool IsWeekday(string day)
    {
        return day.IsNoneOf("Saturday", "Sunday");
    }

Well it doesn´t make my day but it makes typing code slightly faster 🙂

Advertisements

Deploying a certificate into the Trusted Root store in Windows Azure Cloud Services

In a recent project at Tekaris I had to fetch data from an external webservice. The service was only accessible with a certificate. No credential based authentication was possible. So the provider sent me the required certificate which I imported to my local developer machine. Everything worked as excepected as long as it came to deployment.

The following environment is given:

  • Visual Studio 2013
  • Windows Azure Cloud Service
  • Windows Azure Worker Role

In order to deploy the certificate the following steps are necessary:

  • Upload the certificate to Azure. It has to be a .pfx  or .cer file containing the private key and all other certificates in the certificate path
  • Configure the certificates in the Worker Role project of your Cloud Service in Visual Studio

The upload of the certificate is quite simple. Connect to the Azure Poral, select your Cloud Service and switch to the Certificates tab. There you can easily upload the .pfx or .cer file. You need the password that was used when exporting the certificate. After the upload you can see all certificates within the certificate path and their thumbprint.

azure_uploaded_certs

To configure which certificates are deployed to the target machine open the properties of the Worker Role in your cloud project (not of the Worker Role project itself). In the Certificates section add the required certificates. In this post I´ve described how to get the thumbprint of a certificate.

In my case I had the following certificate path:

 

certificate_path_3

 

When I was configuring the certificates in the Worker Role project I was not able to set Root as the store for the root certificate. I got the following errormessage:

Installing a certificate to the LocalMachine/Root store is not supported. 

cert_root_store_not_possible

In order to get the deployment package built I had to change from Root to Trust. That meant that Azure deployed the Root Certificate into the Enterprise Trust Store on the target machine which caused a broken certificate path.

So after the deployment I connected to the target machine via RDP and moved the Root Certificate manually to the correct store. But this step would be necessary every time I deploy the package into a new environment or when the Azure Scaling framework would increase the number of machines. Not a feasible solution. That must happen automatically.

I decided to write some logic that checks on start of the Worker Role whether the certificate is in the correct store and moves it there if necessary. The following code shows only an example how to move a certificate from a defined source to a defined target store by its friendly name. My productive solution is a lot more flexible and configurable 😉

        public void EnsureCorrectRootCertificateStore()
        {
            var certificateFriendlyName = "Friendly_Name_Of_The_Certificate";

            var trustedRootAuthoritiesStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
            trustedRootAuthoritiesStore.Open(OpenFlags.MaxAllowed);

            // Check whether the certificate is already in the correct store
            foreach (var rootCertificates in trustedRootAuthoritiesStore.Certificates)
            {
                if (rootCertificates.FriendlyName == certificateFriendlyName)
                {
                    trustedRootAuthoritiesStore.Close();
                    return;
                }
            }

            var enterpriseTrustStore = new X509Store("Trust", StoreLocation.LocalMachine);
            enterpriseTrustStore.Open(OpenFlags.MaxAllowed);

            // Search for the certificate in the "Enterprise Trust" store
            foreach (var cert in enterpriseTrustStore.Certificates)
            {
                if (cert.FriendlyName != certificateFriendlyName)
                    continue;

                // Remove it from "Enterprise Trust"
                enterpriseTrustStore.Remove(cert);

                // Add it to "Trusted Root Authorities"
                trustedRootAuthoritiesStore.Add(cert);

                trustedRootAuthoritiesStore.Close();
                break;
            }

            enterpriseTrustStore.Close();
        }

One additional thing is necessary to get the code working. The Worker Role must run in elevated mode. Otherwise the access to the Trusted Root Authorities Store would be denied.

Open the ServiceDefinition.csdef file of your Cloud project. Inside the WorkerRole section add an element with the name “Runtime” and the attribute “executionContext” with “elevated” as value. Example:

  <WorkerRole name="MyWorkerRole" vmsize="ExtraSmall">
    <Runtime executionContext="elevated">
    </Runtime>
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
    <ConfigurationSettings/>
    <Certificates>
      <Certificate name="my.certificate" storeLocation="LocalMachine" storeName="My" />
      <Certificate name="Intermediate" storeLocation="LocalMachine" storeName="CA" />
      <Certificate name="Root" storeLocation="LocalMachine" storeName="Trust" />
    </Certificates>
  </WorkerRole>

So that´s it. It took me some time to get all these pieces together and hopefully these lines would prevent you from having the same “nice” experience 🙂

Creating a HTML E-Mail with images from embedded resources

In my last post I described a way to create a PDF from HTML with images retrieved from embedded resources of a .NET library. Based on that I will show the necessary steps for using exactly the same images to create a HTML E-Mail. A common way I use in projects at Tekaris.

I use a similar XSLT to generate some HTML content:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                              exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>EmbeddedImage</title>
      </head>
      <body>
        <img src="cid:header_image" />
        <div>The image is stored as an embedded resource.</div>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

The src-attribute of the image tag contains a CID (MIME content ID) and references an inline attachment of the mail object with the name “header_image”. The following code shows how to add the image as inline content:

var att = new Attachment(ms, new ContentType("image/png"));
att.ContentDisposition.Inline = true;
att.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
att.ContentId = "header_image";
mailMessage.Attachments.Add(att);

Here is the complete code:

string html;

using (var xsltStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("EmbeddedImage.Resources.Mail.xslt"))
{
	var reader = XmlReader.Create(xsltStream);
	var xslt = new XslCompiledTransform();
	xslt.Load(reader);

	using (var ms = new MemoryStream())
	{
		xslt.Transform(new XmlDocument(), new XsltArgumentList(), ms);
		ms.Position = 0;
		using (var r = new StreamReader(ms))
		{
			html = r.ReadToEnd();
		}
	}
}

var mailMessage = new MailMessage
{
	From = new MailAddress("sender@anydomain.com"),
	Subject = "Embedded image test",
	IsBodyHtml = true,
	Body = html
};

mailMessage.To.Add("recipient@anydomain.com");

using (var ms = Assembly.GetExecutingAssembly().GetManifestResourceStream("EmbeddedImage.Resources.image.jpg"))
{
	var att = new Attachment(ms, new ContentType("image/png"));
	att.ContentDisposition.Inline = true;
	att.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
	att.ContentId = "header_image";
	mailMessage.Attachments.Add(att);

	var smtp = new SmtpClient("my.mail.server");
	smtp.Send(mailMessage);
}

And the mail should look like this:

embedded_image_mail