Monthly Archives: November 2012

HtmlHelper for Javascript Script Elements (Tags)

I wrote an HtmlHelper for Javascript elements which, I believe, makes for a more maintainable codebase for adding script elements to a view:

        public enum JavascriptPathType
        {
            Relative = 0,
            FullWebPath = 1
        };

        public static MvcHtmlString Script(this HtmlHelper helper, string jsFileName, JavascriptPathType pathType)
        {
            // Instantiate a UrlHelper
            var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);

            // Create tag builder
            var builder = new TagBuilder("script");

            switch (pathType)
            {
                case JavascriptPathType.Relative: builder.MergeAttribute("src", urlHelper.Content("~/Scripts/" + jsFileName));
                    break;
                case JavascriptPathType.FullWebPath: builder.MergeAttribute("src", urlHelper.Content(jsFileName));
                    break;
            }

            // Add attributes
            builder.MergeAttribute("type", "text/javascript");

            // Render tag. Note: script tags have to have an End tag and cannot be self-closing.
            return new MvcHtmlString(builder.ToString(TagRenderMode.Normal));
        }

The most common scenario is where your javscript file is located in the Scripts directory of your project, in which case, all you need to do is pass in the name of the javascript file:

@Html.Script("jquery-1.8.2.min.js", JavascriptPathType.Relative);

This saves you from typing the script tags and the text type=”text/javascript” everytime.
I also added the custom enum JavascriptPathType to account for scenarios where the src of the script tag is pointing to someplace other than within your own project. For example, if you were using the Google maps API, the usage would be:

@Html.Script("http://maps.google.com/maps/api/js?sensor=false", JavascriptPathType.FullWebPath);

I’m thinking next will be the same kind of helper for Css files.

Signing a Project and InternalsVisibleTo – Extract a Public Key for the Unit Test Project

I recently completed a project and went to give it a strong name by signing it, when an interesting thing happened. It didn’t compile anymore. The relevant error message was Friend assembly reference ‘WinFormsMvp.UnitTests’ is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.
Upon investigation, I discovered what was going on.

One of my unit tests needed access to the internals of a class in my project i.e. I had a class with the protection level of internal being exposed to my unit tests. This was done using the following line of code in the AssemblyInfo class:

[assembly: InternalsVisibleTo("WinFormsMvp.UnitTests")]

However, when I signed the project, the solution wouldn’t build because the Unit Test project also needs to be signed. A strong-named assembly can only reference strong-named assemblies.

So, the solution:

  1. create a separate strong-name key for the unit test project:
    sn -k WinformsMVPTestsKey.snk
  2. extract the public key for the key you just created (prepare yourself for a big string):
    sn –tp WinformsMVPTestsKey.snk
  3. add the extra detail into the line of the AssemblyInfo class described above, assigning the public key string to the PublicKey value:
[assembly: InternalsVisibleTo("WinFormsMvp.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100eb6fea45976e16daadfd3f49c17d7d8abec952b6acd435ceb9ea24efdcfe7b2a2a528f04a6a8269ee88a2cf4b839668a11a580caeab03762abf968cff05d0107c786dc5b7d9d97b14a13277df132222350ad4dc1dd24c03b1d10db168066fbe8ddf3f49b04b6248264479d21bfdabd79b68291da2d62a5ab17fc55819869a4e9")]

That’s how it’s done!