Monthly Archives: April 2012

ASP.NET MVC 3 LabelFor Html Helper with HtmlAttributes

ASP.NET MVC has lots of html helpers to take models and generate html controls in your views. Most of them support passing in an anonymous object which is translated into html attributes on the markup for the element. For example:

    @Html.TextBoxFor(m => m.SomeProperty, new { foo = "bar" })

Which becomes this:

     <input type="text" name="SomeProperty" id="SomeProperty" foo="bar" />

There is however a shortcoming in one of these helpers. LabelFor does not support passing the HtmlAttributes anonymous object. They’ve added support for that into ASP.NET MVC 4 but in the meantime, I’ve written the helper. Here it is.

public static MvcHtmlString LabelFor(
            this HtmlHelper html,
            Expression<Func> expression,
            object htmlAttributes = null)
        {
            var htmlAttributesDict = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)

            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);

            var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);

            string resolvedLabelText = 
                metadata.DisplayName ?? 
                metadata.PropertyName ?? 
                htmlFieldName.Split('.').Last();

            if (String.IsNullOrEmpty(resolvedLabelText))
            {
                return MvcHtmlString.Empty;
            }

            var tagBuilder = new TagBuilder("label");

            tagBuilder.Attributes.Add("for", TagBuilder.CreateSanitizedId(
                html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName)));

            tagBuilder.SetInnerText(resolvedLabelText);
            tagBuilder.MergeAttributes(htmlAttributesDict, replaceExisting: true);

            return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
        }

Enjoy.

Unit testing .NET projects without sacrificing appropriate visibility modifiers

Occasionally I’ll find myself in a position where I need to unit test some code that has internals that are set privately at runtime. Today I found myself in such a position, and I used some reflection to solve the need. This isn’t something I like to do often; I’d prefer to have code that is testable without reflection, but sometimes the path of least resistance can be ok.

RavenController

The RavenDB documentation has an example of a controller that can be used for managing RavenDB sessions for your derived controllers in ASP.NET MVC. I’ve taken that example and made it a little better, in that I can pass in the store through the constructor from the derived controller, which itself was injected. Here’s what that looks like:

    public abstract class RavenController : Controller
    {
        private readonly IDocumentStore documentStore;

        protected IDocumentSession session { get; private set; }

        protected RavenController(IDocumentStore documentStore)
        {
            this.documentStore = documentStore;
        }

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            this.session = this.documentStore.OpenSession();
        }

        protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (filterContext.IsChildAction)
            {
                return;
            }

            using (this.session)
            {
                if (filterContext.Exception != null)
                {
                    return;
                }

                if (this.Session != null)
                {
                    this.session.SaveChanges();
                }
            }
        }
    }

...

    public class FooController : RavenController
    {
        public FooController(IDocumentStore documentStore)
            : base(documentStore)
        {
        }

        public ActionResult Bar()
        {
            //do some stuff with the session here
        }

        ...

    }

No Framework Help

Now, when it comes time to unit test a controller such as this, it’s a little challenging. One nice thing with RavenDB is you can ‘new’ up FooController, and pass it a RavenDB embedded in-memory store to test with:

var store = new EmbeddableDocumentStore()
{
    RunInMemory = true,
};

store.Initialize();

using (var entriesController = new EntriesController(store))
{
    ...
}

The problem is that once you try to call your action directly off this object, you won’t have the benefit of the OnActionExecuting/OnActionExecuted execution ahead/behind your code. Therefor, the session in this case will be null, and the test will fail with a NullReferenceException.

It IS possible to write a whole bunch of ceremony to get this mocked and wired up, but in my opinion it’s not worth the extra 10-20 lines of code just for that.

Dirty Reflection Tricks

I want to set that session property’s private setter. Here’s how I can do that with reflection:

typeof(FooController).BaseType
    .GetProperty("session", BindingFlags.NonPublic | BindingFlags.Instance)
    .SetValue(fooControllerInstance, session, null);

If that makes you feel gross, good, it’s supposed to. But it gets the job done, and you can get on with testing FooController’s action with your embedded in-memory test store without concerning yourself too much with the RavenController infrastructure.