Posts Tagged Microsoft

Intercept values using Microsoft Moles

Recently I needed to test some code in the most untestable codebase I’ve ever seen. Problem I was experiencing was that the value I needed to test was never exposedm but I knew what happened in the code. So I used Microsoft Moles to capture a value that was calculated in the method but never exposed. Below I’ll demonstrate the technique using a sample.

Let’s start with some code that is located in an external library:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SomeExternalLibrary
{
    public class Utilities
    {

        public bool FormatStringContainsUpperCases(string template, params object[] arguments)
        {
            var formattedString = GetFormattedText(template,arguments);
            return formattedString.ToLower() != formattedString;
        }

        public string GetFormattedText(string t, params object[] a)
        {
            return string.Format(t, a);
        }

    }
}

As you can see in the (useless) piece of code above we have a function that will format a string using a template  and arguments and then evaluate if the formatted string contains uppercases. Now let’s say in a test we want to be sure that the formatted string is as we expect. We need a way to get the formatted result in the method FormatStringContainsUpperCases. This can be done using Microsoft Moles because we can create a mole library of the SomeExternalLibrary.dll which allows us to stub the Utilities class.

Create Moles Assembly for the library

Once the Moles library is created we can start writing the Test code. Below you can see the entire test class:

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SomeExternalLibrary;
using SomeExternalLibrary.Moles;

namespace SomeTestProject
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        [HostType("Moles")]
        public void TestUtilities()
        {
            var inputTemplate = "this is the {0}";
            var expectedFormattedString = "this is the Template";

            var formattedString = "";

            var classUnderTest = new Utilities();

            MUtilities.AllInstances.GetFormattedTextStringObjectArray = (s, template, arguments) =>
            {
                MUtilities.AllInstances.GetFormattedTextStringObjectArray = null;
                formattedString = classUnderTest.GetFormattedText(template, arguments);
                return formattedString;
            };

            Assert.IsTrue(classUnderTest.FormatStringContainsUpperCases(inputTemplate, "Template"));
            Assert.AreEqual(expectedFormattedString, formattedString);
        }
    }
}

In the test above we know that in the FormatStringContainsUpperCases method the GetFormattedString method is called. We setup interception using the MUtilities stub and attach a delegate to the GetFormattedString method for all instances of the Utilities class.

Next we remove the delegate we have just attached. If you do not do this the next line of code will cause a StackOverflowException since the code will get in an endless loop calling itself over and over.

MUtilities.AllInstances.GetFormattedTextStringObjectArray = null;

After removing the delegate we can call the original method GetFormattedString on the original class Utilities. This will then return the same result as it would when called in the FormatStringContainsUpperCases method. This result we can store in variable. The last step is to return variable so the calling code can finish correctly.

So to intercept a call you:

  1. Attach a delegate that will handle the interception.
  2. In the delegate body remove the interception delegate to prevent a StackOverflowException
  3. Call the original method and store the result in a variable
  4. Return the variable so the calling code can execute as if it would without the interception.
To learn more about Microsoft Moles go here: http://research.microsoft.com/en-us/projects/moles/

, , ,

No Comments

PART 2: How to get the mime type of a file using the name of a file in C#

Following up on a comment that was posted in my previous post I updated my library to first look in a hard coded list of extensions to see if I can find a corresponding mime type. I must admit that I got a bit inspired by the article Getting MIME types from extension by Pieter Joost van de Sande. I did however updated it to be more .net 4.0 by using the new Lazy<> which lets you do lazy loading. I also replaced the HashTable by a SortedDictionary<string,string>

So the code I used to look up the mime type has changed to this:

    string fileExtension = System.IO.Path.GetExtension(fileName).ToLower();

    var valueInTable = MimeTypeTable.MimeTypes.Value[fileExtension];
    if (valueInTable != null)
       return valueInTable as string;

    Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(fileExtension);
    if (rk != null && rk.GetValue("Content Type") != null)
       return rk.GetValue("Content Type").ToString();

    return null;

As you can see I now do a lookup in the MimeTypeTable and if I have no result only then I’ll go into the registry to try having better luck there. Here is the implementation of the MimeTypeTable class (beware it’s quite long) also the download of the new library is at the end of this post:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Suddenelfilio.ExtensionMethods.IO
{
    internal sealed class MimeTypeTable
    {
        internal static Lazy<SortedDictionary<string, string>> MimeTypes
        {
            get
            {
                return new Lazy<SortedDictionary<string,string>>(() => LoadTable(), true);
            }
        }

        private static SortedDictionary<string, string> LoadTable()
        {
            SortedDictionary<string, string> types = new SortedDictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);

            types.Add(".3dm", "x-world/x-3dmf");
            types.Add(".3dmf", "x-world/x-3dmf");
            types.Add(".aab", "application/x-authorware-bin");
            types.Add(".aam", "application/x-authorware-map");
            types.Add(".aas", "application/x-authorware-seg");
            types.Add(".abc", "text/vnd.abc");
            types.Add(".acgi", "text/html");
            types.Add(".afl", "video/animaflex");
            types.Add(".ai", "application/postscript");
            types.Add(".aif", "audio/aiff");
            types.Add(".aifc", "audio/aiff");
            types.Add(".aiff", "audio/aiff");
            types.Add(".aim", "application/x-aim");
            types.Add(".aip", "text/x-audiosoft-intra");
            types.Add(".ani", "application/x-navi-animation");
            types.Add(".aos", "application/x-nokia-9000-communicator-add-on-software");
            types.Add(".aps", "application/mime");
            types.Add(".art", "image/x-jg");
            types.Add(".asf", "video/x-ms-asf");
            types.Add(".asm", "text/x-asm");
            types.Add(".asp", "text/asp");
            types.Add(".asx", "application/x-mplayer2");
            types.Add(".au", "audio/x-au");
            types.Add(".avi", "video/avi");
            types.Add(".avs", "video/avs-video");
            types.Add(".bcpio", "application/x-bcpio");
            types.Add(".bm", "image/bmp");
            types.Add(".bmp", "image/bmp");
            types.Add(".boo", "application/book");
            types.Add(".book", "application/book");
            types.Add(".boz", "application/x-bzip2");
            types.Add(".bsh", "application/x-bsh");
            types.Add(".bz", "application/x-bzip");
            types.Add(".bz2", "application/x-bzip2");
            types.Add(".c", "text/plain");
            types.Add(".c++", "text/plain");
            types.Add(".cat", "application/vnd.ms-pki.seccat");
            types.Add(".cc", "text/plain");
            types.Add(".ccad", "application/clariscad");
            types.Add(".cco", "application/x-cocoa");
            types.Add(".cdf", "application/cdf");
            types.Add(".cer", "application/pkix-cert");
            types.Add(".cha", "application/x-chat");
            types.Add(".chat", "application/x-chat");
            types.Add(".class", "application/java");
            types.Add(".conf", "text/plain");
            types.Add(".cpio", "application/x-cpio");
            types.Add(".cpp", "text/plain");
            types.Add(".cpt", "application/x-cpt");
            types.Add(".crl", "application/pkix-crl");
            types.Add(".crt", "application/pkix-cert");
            types.Add(".csh", "application/x-csh");
            types.Add(".css", "text/css");
            types.Add(".cxx", "text/plain");
            types.Add(".dcr", "application/x-director");
            types.Add(".deepv", "application/x-deepv");
            types.Add(".def", "text/plain");
            types.Add(".der", "application/x-x509-ca-cert");
            types.Add(".dif", "video/x-dv");
            types.Add(".dir", "application/x-director");
            types.Add(".dl", "video/dl");
            types.Add(".doc", "application/msword");
            types.Add(".dot", "application/msword");
            types.Add(".dp", "application/commonground");
            types.Add(".drw", "application/drafting");
            types.Add(".dv", "video/x-dv");
            types.Add(".dvi", "application/x-dvi");
            types.Add(".dwf", "drawing/x-dwf (old)");
            types.Add(".dwg", "application/acad");
            types.Add(".dxf", "application/dxf");
            types.Add(".dxr", "application/x-director");
            types.Add(".el", "text/x-script.elisp");
            types.Add(".elc", "application/x-elc");
            types.Add(".eps", "application/postscript");
            types.Add(".es", "application/x-esrehber");
            types.Add(".etx", "text/x-setext");
            types.Add(".evy", "application/envoy");
            types.Add(".f", "text/plain");
            types.Add(".f77", "text/plain");
            types.Add(".f90", "text/plain");
            types.Add(".fdf", "application/vnd.fdf");
            types.Add(".fif", "image/fif");
            types.Add(".fli", "video/fli");
            types.Add(".flo", "image/florian");
            types.Add(".flx", "text/vnd.fmi.flexstor");
            types.Add(".fmf", "video/x-atomic3d-feature");
            types.Add(".for", "text/plain");
            types.Add(".fpx", "image/vnd.fpx");
            types.Add(".frl", "application/freeloader");
            types.Add(".funk", "audio/make");
            types.Add(".g", "text/plain");
            types.Add(".g3", "image/g3fax");
            types.Add(".gif", "image/gif");
            types.Add(".gl", "video/gl");
            types.Add(".gsd", "audio/x-gsm");
            types.Add(".gsm", "audio/x-gsm");
            types.Add(".gsp", "application/x-gsp");
            types.Add(".gss", "application/x-gss");
            types.Add(".gtar", "application/x-gtar");
            types.Add(".gz", "application/x-gzip");
            types.Add(".gzip", "application/x-gzip");
            types.Add(".h", "text/plain");
            types.Add(".hdf", "application/x-hdf");
            types.Add(".help", "application/x-helpfile");
            types.Add(".hgl", "application/vnd.hp-HPGL");
            types.Add(".hh", "text/plain");
            types.Add(".hlb", "text/x-script");
            types.Add(".hlp", "application/x-helpfile");
            types.Add(".hpg", "application/vnd.hp-HPGL");
            types.Add(".hpgl", "application/vnd.hp-HPGL");
            types.Add(".hqx", "application/binhex");
            types.Add(".hta", "application/hta");
            types.Add(".htc", "text/x-component");
            types.Add(".htm", "text/html");
            types.Add(".html", "text/html");
            types.Add(".htmls", "text/html");
            types.Add(".htt", "text/webviewhtml");
            types.Add(".htx", "text/html");
            types.Add(".ice", "x-conference/x-cooltalk");
            types.Add(".ico", "image/x-icon");
            types.Add(".idc", "text/plain");
            types.Add(".ief", "image/ief");
            types.Add(".iefs", "image/ief");
            types.Add(".iges", "application/iges");
            types.Add(".igs", "application/iges");
            types.Add(".ima", "application/x-ima");
            types.Add(".imap", "application/x-httpd-imap");
            types.Add(".inf", "application/inf");
            types.Add(".ins", "application/x-internett-signup");
            types.Add(".ip", "application/x-ip2");
            types.Add(".isu", "video/x-isvideo");
            types.Add(".it", "audio/it");
            types.Add(".iv", "application/x-inventor");
            types.Add(".ivr", "i-world/i-vrml");
            types.Add(".ivy", "application/x-livescreen");
            types.Add(".jam", "audio/x-jam");
            types.Add(".jav", "text/plain");
            types.Add(".java", "text/plain");
            types.Add(".jcm", "application/x-java-commerce");
            types.Add(".jfif", "image/jpeg");
            types.Add(".jfif-tbnl", "image/jpeg");
            types.Add(".jpe", "image/jpeg");
            types.Add(".jpeg", "image/jpeg");
            types.Add(".jpg", "image/jpeg");
            types.Add(".jps", "image/x-jps");
            types.Add(".js", "application/x-javascript");
            types.Add(".jut", "image/jutvision");
            types.Add(".kar", "audio/midi");
            types.Add(".ksh", "text/x-script.ksh");
            types.Add(".la", "audio/nspaudio");
            types.Add(".lam", "audio/x-liveaudio");
            types.Add(".latex", "application/x-latex");
            types.Add(".list", "text/plain");
            types.Add(".lma", "audio/nspaudio");
            types.Add(".log", "text/plain");
            types.Add(".lsp", "application/x-lisp");
            types.Add(".lst", "text/plain");
            types.Add(".lsx", "text/x-la-asf");
            types.Add(".ltx", "application/x-latex");
            types.Add(".m", "text/plain");
            types.Add(".m1v", "video/mpeg");
            types.Add(".m2a", "audio/mpeg");
            types.Add(".m2v", "video/mpeg");
            types.Add(".m3u", "audio/x-mpequrl");
            types.Add(".man", "application/x-troff-man");
            types.Add(".map", "application/x-navimap");
            types.Add(".mar", "text/plain");
            types.Add(".mbd", "application/mbedlet");
            types.Add(".mc$", "application/x-magic-cap-package-1.0");
            types.Add(".mcd", "application/mcad");
            types.Add(".mcf", "image/vasa");
            types.Add(".mcp", "application/netmc");
            types.Add(".me", "application/x-troff-me");
            types.Add(".mht", "message/rfc822");
            types.Add(".mhtml", "message/rfc822");
            types.Add(".mid", "audio/midi");
            types.Add(".midi", "audio/midi");
            types.Add(".mif", "application/x-mif");
            types.Add(".mime", "message/rfc822");
            types.Add(".mjf", "audio/x-vnd.AudioExplosion.MjuiceMediaFile");
            types.Add(".mjpg", "video/x-motion-jpeg");
            types.Add(".mm", "application/base64");
            types.Add(".mme", "application/base64");
            types.Add(".mod", "audio/mod");
            types.Add(".moov", "video/quicktime");
            types.Add(".mov", "video/quicktime");
            types.Add(".movie", "video/x-sgi-movie");
            types.Add(".mp2", "video/mpeg");
            types.Add(".mp3", "audio/mpeg3");
            types.Add(".mpa", "audio/mpeg");
            types.Add(".mpc", "application/x-project");
            types.Add(".mpe", "video/mpeg");
            types.Add(".mpeg", "video/mpeg");
            types.Add(".mpg", "video/mpeg");
            types.Add(".mpga", "audio/mpeg");
            types.Add(".mpp", "application/vnd.ms-project");
            types.Add(".mpt", "application/x-project");
            types.Add(".mpv", "application/x-project");
            types.Add(".mpx", "application/x-project");
            types.Add(".mrc", "application/marc");
            types.Add(".ms", "application/x-troff-ms");
            types.Add(".mv", "video/x-sgi-movie");
            types.Add(".my", "audio/make");
            types.Add(".mzz", "application/x-vnd.AudioExplosion.mzz");
            types.Add(".nap", "image/naplps");
            types.Add(".naplps", "image/naplps");
            types.Add(".nc", "application/x-netcdf");
            types.Add(".ncm", "application/vnd.nokia.configuration-message");
            types.Add(".nif", "image/x-niff");
            types.Add(".niff", "image/x-niff");
            types.Add(".nix", "application/x-mix-transfer");
            types.Add(".nsc", "application/x-conference");
            types.Add(".nvd", "application/x-navidoc");
            types.Add(".oda", "application/oda");
            types.Add(".omc", "application/x-omc");
            types.Add(".omcd", "application/x-omcdatamaker");
            types.Add(".omcr", "application/x-omcregerator");
            types.Add(".p", "text/x-pascal");
            types.Add(".p10", "application/pkcs10");
            types.Add(".p12", "application/pkcs-12");
            types.Add(".p7a", "application/x-pkcs7-signature");
            types.Add(".p7c", "application/pkcs7-mime");
            types.Add(".p7m", "application/pkcs7-mime");
            types.Add(".p7r", "application/x-pkcs7-certreqresp");
            types.Add(".p7s", "application/pkcs7-signature");
            types.Add(".part", "application/pro_eng");
            types.Add(".pas", "text/pascal");
            types.Add(".pbm", "image/x-portable-bitmap");
            types.Add(".pcl", "application/x-pcl");
            types.Add(".pct", "image/x-pict");
            types.Add(".pcx", "image/x-pcx");
            types.Add(".pdb", "chemical/x-pdb");
            types.Add(".pdf", "application/pdf");
            types.Add(".pfunk", "audio/make");
            types.Add(".pgm", "image/x-portable-graymap");
            types.Add(".pic", "image/pict");
            types.Add(".pict", "image/pict");
            types.Add(".pkg", "application/x-newton-compatible-pkg");
            types.Add(".pko", "application/vnd.ms-pki.pko");
            types.Add(".pl", "text/plain");
            types.Add(".plx", "application/x-PiXCLscript");
            types.Add(".pm", "image/x-xpixmap");
            types.Add(".pm4", "application/x-pagemaker");
            types.Add(".pm5", "application/x-pagemaker");
            types.Add(".png", "image/png");
            types.Add(".pnm", "application/x-portable-anymap");
            types.Add(".pot", "application/mspowerpoint");
            types.Add(".pov", "model/x-pov");
            types.Add(".ppa", "application/vnd.ms-powerpoint");
            types.Add(".ppm", "image/x-portable-pixmap");
            types.Add(".pps", "application/mspowerpoint");
            types.Add(".ppt", "application/mspowerpoint");
            types.Add(".ppz", "application/mspowerpoint");
            types.Add(".pre", "application/x-freelance");
            types.Add(".prt", "application/pro_eng");
            types.Add(".ps", "application/postscript");
            types.Add(".pvu", "paleovu/x-pv");
            types.Add(".pwz", "application/vnd.ms-powerpoint");
            types.Add(".py", "text/x-script.phyton");
            types.Add(".pyc", "applicaiton/x-bytecode.python");
            types.Add(".qcp", "audio/vnd.qcelp");
            types.Add(".qd3", "x-world/x-3dmf");
            types.Add(".qd3d", "x-world/x-3dmf");
            types.Add(".qif", "image/x-quicktime");
            types.Add(".qt", "video/quicktime");
            types.Add(".qtc", "video/x-qtc");
            types.Add(".qti", "image/x-quicktime");
            types.Add(".qtif", "image/x-quicktime");
            types.Add(".ra", "audio/x-pn-realaudio");
            types.Add(".ram", "audio/x-pn-realaudio");
            types.Add(".ras", "application/x-cmu-raster");
            types.Add(".rast", "image/cmu-raster");
            types.Add(".rexx", "text/x-script.rexx");
            types.Add(".rf", "image/vnd.rn-realflash");
            types.Add(".rgb", "image/x-rgb");
            types.Add(".rm", "application/vnd.rn-realmedia");
            types.Add(".rmi", "audio/mid");
            types.Add(".rmm", "audio/x-pn-realaudio");
            types.Add(".rmp", "audio/x-pn-realaudio");
            types.Add(".rng", "application/ringing-tones");
            types.Add(".rnx", "application/vnd.rn-realplayer");
            types.Add(".roff", "application/x-troff");
            types.Add(".rp", "image/vnd.rn-realpix");
            types.Add(".rpm", "audio/x-pn-realaudio-plugin");
            types.Add(".rss", "text/xml");
            types.Add(".rt", "text/richtext");
            types.Add(".rtf", "text/richtext");
            types.Add(".rtx", "text/richtext");
            types.Add(".rv", "video/vnd.rn-realvideo");
            types.Add(".s", "text/x-asm");
            types.Add(".s3m", "audio/s3m");
            types.Add(".sbk", "application/x-tbook");
            types.Add(".scm", "application/x-lotusscreencam");
            types.Add(".sdml", "text/plain");
            types.Add(".sdp", "application/sdp");
            types.Add(".sdr", "application/sounder");
            types.Add(".sea", "application/sea");
            types.Add(".set", "application/set");
            types.Add(".sgm", "text/sgml");
            types.Add(".sgml", "text/sgml");
            types.Add(".sh", "text/x-script.sh");
            types.Add(".shar", "application/x-bsh");
            types.Add(".shtml", "text/html");
            types.Add(".sid", "audio/x-psid");
            types.Add(".sit", "application/x-sit");
            types.Add(".skd", "application/x-koan");
            types.Add(".skm", "application/x-koan");
            types.Add(".skp", "application/x-koan");
            types.Add(".skt", "application/x-koan");
            types.Add(".sl", "application/x-seelogo");
            types.Add(".smi", "application/smil");
            types.Add(".smil", "application/smil");
            types.Add(".snd", "audio/basic");
            types.Add(".sol", "application/solids");
            types.Add(".spc", "application/x-pkcs7-certificates");
            types.Add(".spl", "application/futuresplash");
            types.Add(".spr", "application/x-sprite");
            types.Add(".sprite", "application/x-sprite");
            types.Add(".src", "application/x-wais-source");
            types.Add(".ssi", "text/x-server-parsed-html");
            types.Add(".ssm", "application/streamingmedia");
            types.Add(".sst", "application/vnd.ms-pki.certstore");
            types.Add(".step", "application/step");
            types.Add(".stl", "application/sla");
            types.Add(".stp", "application/step");
            types.Add(".sv4cpio", "application/x-sv4cpio");
            types.Add(".sv4crc", "application/x-sv4crc");
            types.Add(".svf", "image/x-dwg");
            types.Add(".svr", "application/x-world");
            types.Add(".swf", "application/x-shockwave-flash");
            types.Add(".t", "application/x-troff");
            types.Add(".talk", "text/x-speech");
            types.Add(".tar", "application/x-tar");
            types.Add(".tbk", "application/toolbook");
            types.Add(".tcl", "text/x-script.tcl");
            types.Add(".tcsh", "text/x-script.tcsh");
            types.Add(".tex", "application/x-tex");
            types.Add(".texi", "application/x-texinfo");
            types.Add(".texinfo", "application/x-texinfo");
            types.Add(".text", "text/plain");
            types.Add(".tgz", "application/x-compressed");
            types.Add(".tif", "image/tiff");
            types.Add(".tiff", "image/tiff");
            types.Add(".tr", "application/x-troff");
            types.Add(".tsi", "audio/tsp-audio");
            types.Add(".tsp", "audio/tsplayer");
            types.Add(".tsv", "text/tab-separated-values");
            types.Add(".turbot", "image/florian");
            types.Add(".txt", "text/plain");
            types.Add(".uil", "text/x-uil");
            types.Add(".uni", "text/uri-list");
            types.Add(".unis", "text/uri-list");
            types.Add(".unv", "application/i-deas");
            types.Add(".uri", "text/uri-list");
            types.Add(".uris", "text/uri-list");
            types.Add(".ustar", "multipart/x-ustar");
            types.Add(".uu", "text/x-uuencode");
            types.Add(".uue", "text/x-uuencode");
            types.Add(".vcd", "application/x-cdlink");
            types.Add(".vcs", "text/x-vCalendar");
            types.Add(".vda", "application/vda");
            types.Add(".vdo", "video/vdo");
            types.Add(".vew", "application/groupwise");
            types.Add(".viv", "video/vivo");
            types.Add(".vivo", "video/vivo");
            types.Add(".vmd", "application/vocaltec-media-desc");
            types.Add(".vmf", "application/vocaltec-media-file");
            types.Add(".voc", "audio/voc");
            types.Add(".vos", "video/vosaic");
            types.Add(".vox", "audio/voxware");
            types.Add(".vqe", "audio/x-twinvq-plugin");
            types.Add(".vqf", "audio/x-twinvq");
            types.Add(".vql", "audio/x-twinvq-plugin");
            types.Add(".vrml", "application/x-vrml");
            types.Add(".vrt", "x-world/x-vrt");
            types.Add(".vsd", "application/x-visio");
            types.Add(".vst", "application/x-visio");
            types.Add(".vsw", "application/x-visio");
            types.Add(".w60", "application/wordperfect6.0");
            types.Add(".w61", "application/wordperfect6.1");
            types.Add(".w6w", "application/msword");
            types.Add(".wav", "audio/wav");
            types.Add(".wb1", "application/x-qpro");
            types.Add(".wbmp", "image/vnd.wap.wbmp");
            types.Add(".web", "application/vnd.xara");
            types.Add(".wiz", "application/msword");
            types.Add(".wk1", "application/x-123");
            types.Add(".wmf", "windows/metafile");
            types.Add(".wml", "text/vnd.wap.wml");
            types.Add(".wmlc", "application/vnd.wap.wmlc");
            types.Add(".wmls", "text/vnd.wap.wmlscript");
            types.Add(".wmlsc", "application/vnd.wap.wmlscriptc");
            types.Add(".word", "application/msword");
            types.Add(".wp", "application/wordperfect");
            types.Add(".wp5", "application/wordperfect");
            types.Add(".wp6", "application/wordperfect");
            types.Add(".wpd", "application/wordperfect");
            types.Add(".wq1", "application/x-lotus");
            types.Add(".wri", "application/mswrite");
            types.Add(".wrl", "application/x-world");
            types.Add(".wrz", "model/vrml");
            types.Add(".wsc", "text/scriplet");
            types.Add(".wsrc", "application/x-wais-source");
            types.Add(".wtk", "application/x-wintalk");
            types.Add(".xbm", "image/x-xbitmap");
            types.Add(".xdr", "video/x-amt-demorun");
            types.Add(".xgz", "xgl/drawing");
            types.Add(".xif", "image/vnd.xiff");
            types.Add(".xl", "application/excel");
            types.Add(".xla", "application/excel");
            types.Add(".xlb", "application/excel");
            types.Add(".xlc", "application/excel");
            types.Add(".xld", "application/excel");
            types.Add(".xlk", "application/excel");
            types.Add(".xll", "application/excel");
            types.Add(".xlm", "application/excel");
            types.Add(".xls", "application/excel");
            types.Add(".xlt", "application/excel");
            types.Add(".xlv", "application/excel");
            types.Add(".xlw", "application/excel");
            types.Add(".xm", "audio/xm");
            types.Add(".xml", "text/xml");
            types.Add(".xmz", "xgl/movie");
            types.Add(".xpix", "application/x-vnd.ls-xpix");
            types.Add(".xpm", "image/xpm");
            types.Add(".x-png", "image/png");
            types.Add(".xsr", "video/x-amt-showrun");
            types.Add(".xwd", "image/x-xwd");
            types.Add(".xyz", "chemical/x-pdb");
            types.Add(".z", "application/x-compressed");
            types.Add(".zip", "application/zip");
            types.Add(".zsh", "text/x-script.zsh");

            return types;
        }
    }
}

Here is the library: Suddenelfilio.ExtensionMethods.zip
Downloaded 204 times


      

, , , , , , , ,

2 Comments

How to get the mime type of a file using the name of a file in C#

UPDATE: in PART 2: How to get the mime type of a file using the name of a file in C# I updated the library so it first tries to look up the mime type in a hard coded table

I recently needed to know the MIME type of a file or a file name. I know this is not that difficult certainly if you know that all the known mime types are stored in the registry of Windows. There is one caveat though, the extension you are resolving must be registered first. For example if you don’t install Adobe Acrobat PDF reader then the .pdf extension is not known and my solution I propose below won’t return any result. What you can do is either add the extension manually to the registry or install the corresponding application on the machine that needs to know about it.

Okay I’ve created a small (at least for the moment) library that allows you to call GetMimiType() on either a string or System.IO.FileInfo instance. Of course when you call this method on a string make sure the value is a valid file name! I’ve created 2 extension methods for this that can both be found in Suddenelfilio.ExtensionMethods.IO.

Here is the code to find a mime type in the registry:


 string fileExtension = System.IO.Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(fileExtension);
if (rk != null && rk.GetValue("Content Type") != null)
return rk.GetValue("Content Type").ToString();

 return null;

Now if you want to use my library and its extension methods below is a sample of a console’s application Program.cs file:


using System;
using System.IO;
using Suddenelfilio.ExtensionMethods.IO;

namespace TestConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            //Using a string with a filename as value.
            string name = "d:\\test.txt";
            Console.WriteLine("mimetype for file {0} is {1}", name, name.GetMimeType());

            FileInfo info = new FileInfo("d:\\test.txt");
            Console.WriteLine("mimetype for file {0} is {1}", info.FullName, info.GetMimeType());

            Console.ReadLine();
        }
    }
}

The result in the console application is the following:

Here is the download containing the dll with the extension methods: Look at the follow up article

, , , , ,

5 Comments

LinkedIn OAuth using Hammock in C# & ASP.NET

UPDATE: Hammock moved to github https://github.com/danielcrenna/hammock

 

Codeplex.com description of Hammock:
Hammock is a REST library for .NET that greatly simplifies consuming and wrapping RESTful services.

I’m currently working on a little web project that needed integration with LinkedIn.com. The LinkedIn API allows for OAuth authorization and authentication. They describe the process of getting a request token, authorizing it by the user and then getting an access token. Standard OAuth you might say. So I needed a way to do this in C# and found the Hammock library. Although Hammock does not only do OAuth I used it for that purpose only at the moment.

Below is the code I wrote to get a request token and send the user to the authorization page at Linkedin:


public void RequestAndAuthorize()
        {
            var credentials = new OAuthCredentials
            {
                CallbackUrl = "http://127.0.0.1/oauth/callback/",
                ConsumerKey = ConfigurationManager.AppSettings["ConsumerKey"],
                ConsumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"],
                Verifier = "123456",
                Type = OAuthType.RequestToken
            };
            var client = new RestClient { Authority = "https://api.linkedin.com/uas/oauth", Credentials = credentials };
            var request = new RestRequest { Path = "requestToken" };
            RestResponse response = client.Request(request);

            string token = response.Content.Split('&amp;').Where(s =&gt; s.StartsWith("oauth_token=")).Single().Split('=')[1];
            string token_secret = response.Content.Split('&amp;').Where(s =&gt; s.StartsWith("oauth_token_secret=")).Single().Split('=')[1];

            Response.Redirect("https://api.linkedin.com/uas/oauth?oauth_token=" + token);
        }

Once the user has authorized your request token the LinkedIn server will redirect the user back to the callback url in this case this is http://127.0.0.1/oauth/callback. Using the returned oauth_token and oauth_token_secret (you got this one while requesting a request token) you can now get an access token so you can start making authenticated API calls from you application on behalf of the user.

This is the code that is used when the callback url is called:


	public void Callback()
        {
            var credentials = new OAuthCredentials
            {
                ConsumerKey = ConfigurationManager.AppSettings["ConsumerKey"],
                ConsumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"],
                Token = token,
                TokenSecret = token_secret,
                Verifier = verifier,
                Type = OAuthType.AccessToken,
                ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
                SignatureMethod = OAuthSignatureMethod.HmacSha1,
                Version = "1.0"
            };
            var client = new RestClient { Authority = "https://api.linkedin.com/uas/oauth", Credentials = credentials, Method = WebMethod.Post };
            var request = new RestRequest { Path = "accessToken" };
            RestResponse response = client.Request(request);
            string content = response.Content;
        }

As you can see Hammock is really nice and allows for easy OAuth authentication/authorization to be used.

, , , , , , , ,

23 Comments

Increase Kooboo performance in IIS 7

Lately I’ve been working with the Kooboo CMS which is built using ASP.NET MVC. I really like the speed Kooboo allows you to build a website with dynamic content. All that fancy footwork comes with a downside. The first time you call a Kooboo application it is really and do mean REALLY slow to start. Cause? Well the Asp.net MVC framework, Microsoft Entity framework and most of all I think the extensive caching mechanism.

I’ve experienced waiting times up till 30 seconds for the first page to appear, now this is not really acceptable for any site I admit. I remembered that there is IIS 7 extension called application warm-up tool that you can configure to call a certain url when the worker process recycles. This will trigger the site to startup again and load up all the caching and stuff. I’m not saying that the next call will be blazingly fast but at least your request will be served much faster.

I’m currently developing several sites using the Kooboo platform and I’m pleasently surprised of the possibilities of the platform. Thumbs up for the creators!

, , , ,

No Comments

UPDATE: MS Tag REST service issues

During the last 24 hours the service has been experiencing some issues when called. This has currently been resolved. If you’ve received an http 500 error code when calling the service please try again. The issue was introduced when I extended the service to record certain metrics. These metrics or stats can be seen on http://tag.ws.suddenelfilio.net/ at the end of the page.

If you experience any other problems please contact me at: mstaglib@suddenelfilio.net

, , , ,

No Comments

WpfToolkit + VisualStateManager + Visual studio .net 2008 = hotfix time

I got into playing a bit with WPF. I had to look at some reference samples that were created by some of my colleagues and I found that I had an issue opening any xaml file in the visual studio .net 2008 designer. The problem was the VisualStateManager.VisualStateGroups that could not be resolved. Appareantly this is some that has been introduced in the WPFToolkit which is used by our development team.

After some Googling for the issue I discovered a Hotfix released by Microsoft that should resolve my issues. The thing about this hotfix was that you also neede to install another hotfix because the fix might break something else. You gotta love the irony in that!

Anyways the hotfixes I’m talking about can be found here:

After installing both hotfixes the problem was gone I can now open the xaml files that use VisualStateManager.

More information about the VisualStateManager itself can be found here: http://windowsclient.net/wpf/wpf35/wpf-35sp1-toolkit-visual-state-manager-overview.aspx

, , , ,

1 Comment

New Windows Live Beta

The Windows Live team released a public beta of the latest innovations in the Windows Live product family.All products have undergone updating and there are also some new things like the Windows Live Sync service.

This Sync service is something I’m looking forward to since I was a user of the Microsoft Live Mesh program. I stopped using Live Mesh because I reached my storage limit and at the time there was no possibility to upgrade. The new Sync service is integrated with you Windows Skydrive storage which – as far as I know – is upgradeable.

Another big change is the Messenger application, it is no longer targeted at “just” IM messaging, but now has an integrated sort of activity stream with social networks like Facebook and Myspace. My guess is that in the future this might expand to other networks as well.

So if you want to try this latest beta release go to: http://bit.ly/deEQxl

Note: this post is written using the latest beta of Windows Live Writer

New Windows Live Writer

, ,

No Comments

MS Tag REST Certificate Issues

This week I received an email telling me that they got an error while using the MS Tag REST  service:

System.ServiceModel.Security.SecurityNegotiationException: Could not establish trust relationship for the SSL/TLS secure channel with authority ‘ws.tag.microsoft.com‘.

As you can see the authority is complaining about the Microsoft domain. The issue was the certificate used by Microsoft’s Tag API was outdated and thus the error was thrown when the  REST service communicated with the Microsoft service.

Since the certificate has been renewed and is now valid till somewhere early 2011 this problem should be resolved.

, , ,

No Comments

Windows 7 x64 + nforce chipset + >= 4 GB RAM + large file copy = disaster

I’ve wasted an entire day AND evening on some stupid issues at work. I reinstalled my portable with windows 7 x64. Only to notice that after 6 hours of installing that some software that I need for work doesn’t play nice with x64 (I know because I tested it in x86 where it works just fine). So I decided to install the x86 version of windows 7. I downloaded it and wanted to copy it to my USB stick only to discover that the file copy got stuck around 700 MB left to copy. It seems there is an issue with windows 7 x64 with at least 4 GB ram of copying large files. Microsoft released a so called hotfix: http://social.technet.microsoft.com/Forums/en-US/w7itprohardware/thread/38f25c1d-de67-4c74-8845-2cd3a15d8e41 but as it turns out my system already had this update and it seems that it doesn’t work at all. So now I’m stuck with an >2GB iso file I can’t copy away from my desktop because copying fails halfway through. I recently upgraded my system to 8GB so downgrading to 32 bits is not an option as the extra 4GB will go to waste. Maybe I should put back windows xp x64?

If you recognize this issue and have found a working solution please let me know by posting a comment!

, , , ,

3 Comments