Tag Archives: ASP.NET MVC

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.

RavenDB: Lessons Learned: Query Includes and Projections

Note: This was originally posted over on the Development @ MSNBC blog.

By default, RavenDB will only allow 30 requests per session. This is part of RavenDB’s “Safe by default” behaviors, to prevent you from making a giant number of RavenDB HTTP requests, which would be a performance quagmire.

Let’s say you have an object graph that you are retrieving from RavenDB that contains referenced documents, and it looks like this:

stories/123
{
  "Headline": "New iPad is key to Apple's bottom line",
  "Author": "Jack Smith",
  "LastPublishedAtUtc": "2012-03-14T23:48:00.0000000+00:00", 
  "PublishStatus": "Published",
  "StoryReferences": 
  {
    "storyreference/456213": 
    {
      "Headline": "New iPhone coming soon",
      "Author": "John Doe"
    }
    "storyreference/789654": 
    {
      "Headline": "New iPad foils reviewers' attempts to find legitimate faults",
      "Author": "Jane Doe"
    }
    "storyreference/555111": 
    {
      "Headline": "Now on Netflix: Search by TV network",
      "Author": "Jack Smith"
    }
    "storyreference/942342": 
    {
      "Headline": "Apple stores to open at 8am for iPad launch",
      "Author": "John Doe"
    }
    ...
  }
}

And let’s say you are interested in getting a small subset of data about the referenced stories for display with the base story. What you DON’T want to do is something like this:

var story = session.Load("stories/123");

foreach(var storyReference in story.RelatedStories)
{
    var otherStory = session.Load(storyReference.Id);
    // ... do something with otherStory ...
}

That will result in the following HTTP traffic back to Raven:

  1. Make a request for ‘story/123′
  2. Make a request for ‘story/456213′
  3. Make a request for ‘story/789654′
  4. Make a request for ‘story/555111′
  5. Make a request for ‘story/942342′
  6. …etc…

You’ll consume unnecessary bandwidth and incur the cost of individual HTTP requests. What you really want to do is have the client make a single HTTP request. Fortunately RavenDB allows you to do that with Includes. A RavenDB include says “Hey server, go get this for me, but before you give it back to me, gather up these other things and return them with the request too so I can deal with them in a moment”.

A few weeks back we had some code that was hitting the 30 requests per session limit. At first we couldn’t understand why, since we do a pretty good job of making sure we only make 1 or 2 requests via Includes. Upon further inspection, it turned out we had misunderstood something about the RavenDB client API.

What’s the problem?

If we have an index that produces projections, in which it produces a server side anonymous entity containing flattened “StoryReferenceIds”, like this (this is a contrived example):

public class Stories_ByReferencedStories : AbstractIndexCreationTask
{
    public class Result
    {
        public string Headline { get; set; }
        public DateTimeOffset? LastPublishedAtUtc { get; set; }
        public IEnumerable StoryReferenceIds { get; set; }
    }

    public Stories_ByReferencedStories()
    {
        this.Map = stories => from story in stories
                              select new
                              {
                                  Headline = story.Headline,
                                  LastPublishedAtUtc = story.LastPublishedAtUtc,
                                  StoryReferenceIds = story.StoryReferences.Select(x => x.Id),
                              };
    }
}

… Then we had previously done something like the following on our Lucene queries against it:

session.Advanced.LuceneQuery()
  .WhereStartsWith("Headline", text)
  .OrderBy("-LastPublishedAtUtc")
  .Include("StoryReferenceIds")

However, it turns out that last Include line doesn’t do anything at all. The Include() call actually operates on the entries identified by the index, NOT the projection. In other words, the stories produced from the query are what the Include() call actually operates against.

So, with that in mind, what we actually want is something like this:

.Include("StoryReferences,Id");

The syntax with the comma may look a little funny, but what it means is “For the StoryReferenceIds entities collection, Include the document identified by the Id property from each referenced document”. So if you had a story with 45 referenced stories in it, instead of making 46 requests back to Raven, you would make only 1 request. That’s much better.

Happy coding.

Raven DB: Lessons Learned: Caching Contexts

Note: This was originally posted over on the Development @ MSNBC blog.

Caching

When you talk about caching in terms of the the full web application stack, you’ve typically got the following layers:

  • Browser cache
  • CDN cache
  • Application output cache
  • Data cache

However, in a application leveraging Raven DB, the last layer actually gets split up into two layers.

Some Background

The way Raven DB operates is by having the client generate HTTP requests, which are sent across the wire to the server. Therefor, the same standard caching mechanisms that HTTP provides are present. This means, that if a request is made, and Raven DB thinks the data hasn’t changed since the last time you requested that same data, then the server responds with HTTP 304 Not Modified, instructing the raven client to continue to use what it got last time.

using (var session = store.OpenSession())
{
    //if the server doesnt have anything different from the last time 
    //this was requested, it wont do any processing, and just return 
    //HTTP 304 Not Modified to the client. the client will then use 
    //what it got last time.
    var foo = session.Load("foos/123");
}

So the first layer of the data cache, you get for free out of the box with Raven. Fortunately the second layer is available as well, if your application needs it.

Aggressive Data Caching

With Raven DB, it’s possible to instruct the client to not even ask the server for data again, thereby skipping the HTTP request, even if it might result in a 304. Here’s what that looks like:

using (var session = store.OpenSession())
{
    //set up an aggressive caching context, instructing the server to not
    //make an http request if it made one within the last 5 seconds
    using (session.Advanced.DocumentStore
        .AggressivelyCacheFor(TimeSpan.FromMinutes(5)))
    {
        //may or may not make a request
        var foo = session.Load("foos/123");  
    }
}

Runtime Configuration?

We made mention in a previous blog post about a runtime configuration setup that we’ve provided our ops team with. Having the ability to control the TTL on the Raven runtime configuration seems like a prime candidate to use with this. We wired up the runtime configuration much the same as the output caching runtime configuration from the other blog post.

Clever

Now, to use output caching, it was a simple line to apply the [ConfiguredOutputCache] attribute to our controller actions. However, with the raven data caching, it’s a violation of DRY to have to open an aggressive caching context, and pass in a runtime configuration value everywhere it’s needed. So, with that in mind, we came up with an extension method to encapsulate that behavior. We thought this was very clever, but it actually turned out to be quite stupid. Can you spot the problem?

public static class DataCachingExtensions
{
    public static T LoadAndCache(this IDocumentSession session, string id)
    {
        using (session.Advanced.DocumentStore.AggressivelyCacheFor(
            CacheSettings.RavenAggressiveCachingDurationSeconds))
        {
            return session.Load(id);
        }
    }

    public static IRavenQueryable QueryAndCache(
        this IDocumentSession session)
    {
        using (session.Advanced.DocumentStore.AggressivelyCacheFor(
            CacheSettings.RavenAggressiveCachingDurationSeconds))
        {
            return session.Query();
        }
    }
}

... 

session.LoadAndCache("foos/123");

...

session.QueryAndCache().Where(f => f.Bar == "Baz").ToList();

The first extension method is fine, but the 2nd one doesn’t do anything at all. Why?

It’s because Raven doesn’t actually execute the HTTP query until it’s evaluated. So since we haven’t actually executed the query, and have returned from inside the aggressive caching context, the context was disposed before we ever execute the HTTP query, resulting in no caching.

So after feeling pretty silly, we restructured the extension method to simply return the aggressive caching context, so that the caller can encapsulate the full query including its execution.

public static class DataCachingExtensions
{
    public class NonCachingContext : IDisposable
    {
        public void Dispose() { }
    }

    public static IDisposable GetCachingContext(
        this IDocumentSession session)
    {
        if(CacheSettings.RavenAggressiveCachingDurationSeconds == 0)
        {
            return new NonCachingContext();
        }

        return session.Advanced.DocumentStore.AggressivelyCacheFor(
            CacheSettings.RavenAggressiveCachingDurationSeconds);
    }
}

...

using (var session = store.OpenSession())
{
    using (session.GetCachingContext())
    {
        session.Query().Where(f => f.Bar == "Baz").ToList();
    }
}

It’s worth pointing out that the caching context, when used with a Query, does not actually cache the items returned, but rather just caches the query/response aspect, so subsequent cache-enabled calls to .Loadfor items that were returned from a cache-enabled query context will still make a request take place, if they weren’t already cached by a .Loadcall themselves.

Happy coding!

Performance on-demand; Giving your ops team runtime flexibility

Note: This was originally posted over on the Development @ MSNBC blog.

Performance On Demand

Pretend you are in an operations position, in which your job is to maintain the infrastructure that routes traffic and the servers that serve requests. Wouldn’t it then be nice, if you suddenly had a surge in traffic or a drop in available server hardware (be it expected or unexpected), you could alter the performance characteristics of your web applications?

This is a problem we’ve been tackling with our new set of web apps, and we think we’ve got a pretty good solution in place.

Operations Administration Panel for Runtime Configuration

For starters, we’ve created an administration web application for our operations folks, whose primary purpose is that of runtime configuration. Operations can control various aspects of our systems from this application, including:

  • Logging levels
  • Caching TTLs
  • Database masters/slaves and replication strategies
  • Application settings
  • Network locations for editorial assets
  • Logical service bus participants
  • Etc.

When any of these settings are updated, we send a message on the service bus informing subscribers of changes in the settings they care about. Let’s analyze the one we made reference to above, which will provide ops with a way to dial in performance on demand.

Output Caching

In the administration panel, we’ve provided a settings page where the output caching TTL and data caching TTL can be set for a given application. When this setting is updated, we publish a message on the service bus, which our front end rendering ASP.NET MVC application can subscribe to.

Creating a handler in the rendering application then is pretty easy. We listen for the settings type that corresponds to caching:

    
    public class CacheSettingsUpdater : SettingsChangedHandler
    {
        protected override bool ShouldHandle(string id)
        {
            return string.Equals(
                id,
                CacheSettingsData.StorageId,
                StringComparison.OrdinalIgnoreCase);
        }

        protected override void Update(CacheSettingsData settingsData)
        {
            CacheSettings.UpdateSettings(settingsData);
        }
    }

 

As you can see, the handler can then inform a settings class by calling its “UpdateSettings” method, who keeps a reference to the latest data.

    public static class CacheSettings
    {
        private static CacheSettingsData Data = new CacheSettingsData();

        public static int OutputCacheDurationSeconds
        {
            get
            {
                return
                    Data.CurrentAppCacheParameters
                        .OutputCacheDurationSeconds;
            }
        }

        internal static void UpdateSettings(CacheSettingsData data)
        {
            Data = data;
        }
    }

 

Leveraging it with OutputCacheAttribute

Now, in ASP.NET MVC, there is an action filter for output caching: OutputCacheAttribute. This attribute can be applied at the controller level, or at the individual action level. When an action is run the first time, the framework will cache the result, such that the next request won’t require processing again, and will be delivered from cache. The cached item will be delivered from cache until the TTL/Duration expires. The effect of this is that your application won’t be processing for every request, and will be able to therefor serve more requests.

The issue with connecting up our runtime configuration class from above (CacheSettings) to the OutputCacheAttribute, is that the settings for a filter can only be specified by constants, like so:

    
    [OutputCache(Duration = 10)]
    public ActionResult Index()

 

So, we need to instead create our own action filter, which inherits from OutputCacheAttribute, so we can control where it gets its values from. I’ve simplified this for brevity to just illustrate the Duration extensibility point.

    public class ConfiguredOutputCacheAttribute : OutputCacheAttribute
    {
        public new int Duration
        {
            get { return base.Duration; }
            set
            {
                throw new NotSupportedException(
                    "Duration cannot be set directly. " +
                    "Set from runtime config.");
            }
        }

        public ConfiguredOutputCacheAttribute()
        {
            base.Duration = CacheSettings.OutputCacheDurationSeconds;
        }

        public override void OnActionExecuting(
            ActionExecutingContext filterContext)
        {
            base.Duration = CacheSettings.OutputCacheDurationSeconds;
            base.OnActionExecuting(filterContext);
        }
    }

 

As you can see, when we hit OnActionExecuting, we check the CacheSettings class for the current output cache duration, and set it on the base OutputCacheAttribute class we inherited from. The effect of this, is that during day to day traffic, operations can control the cache TTL.

Then we just apply it where we want to cache:

    [ConfiguredOutputCache]
    public ActionResult Index()

 

Well, how did we do?

Let’s see what it looks like if I simulate light traffic load. The red line indicates request execution time.

The dramatic drop off occurred when I went into the operations administration panel and changed the TTL. The spikes every 10 seconds following the drop off are when the cache duration TTL expired, forcing the page to actually process again.

There are a number of things we can do to enhance the flexibility of this system. For example, we could specify groupings in the operations administration panel that correspond to cache policies, and then simply specify on each instance of our attribute which policy we’d like to use:

    [ConfiguredOutputCache(CachePolicy = "FooCachePolicy")]
    public ActionResult Index(string streamSlug)

 

We think this feature will be particularly valuable in situations where we need more performance on demand, and look forward to extending it to have more flexibility as needed.

Happy coding!

ASP.NET MVC and Razor View Engine Syntax

ASP.NET MVC 2 used the ASPX/WebForms view engine by default, which looks a little like this:

  <ul>
    <% foreach(var thing in stuffs) { %>
        <li><%: thing %></li>
    <% } %>
  </ul>

Code nuggets! That’s pretty painful to have to open and close nuggets all over the place. It begins to look like tag soup, especially with complex output.

So ASP.NET MVC 3 ships using the Razor view engine by default (you can still choose to use ASPX/WebForms if you like pain though). Here’s what Razor looks like to accomplish the same thing:

  <ul>
    @foreach(var thing in stuffs) {
        <li>@thing</li>
    }
  </ul>

That’s much better. With Razor, most things just work as you would expect. No entering and exiting code blocks are needed, and in the rare scenario that you need to escape things, it’s a simple matter of escaping with the ‘@’.