How we do MVC – 4 years later

I’ve taken something like a 3 year hiatus from web applications to work mostly on SOA/messaging systems using NServiceBus, and am recently back on an MVC project. Lots of things have changed, but a lot is still the same.

Most of what we were trying to do in MVC made it in to the core (strongly-typed views, input/output helpers, metadata-driven output etc.) I get lot of questions around AutoMapper – do we still use it and so on. Short answer is yes, long answer is “it depends”. Since AutoMapper is intended to remove code we would have already written, I find my usage of it to be the same, if that’s the code I’m intending to write.

So, in no particular order, some items that stood the test of time:

  • ViewModel pattern and 1:1 ratio from views to view models. It’s getting to the point where I’d rather have a view named after its view model than the action method
  • Display/Editor templated helpers. Though I don’t use MVC’s built-in model any more – they’re just not flexible enough. I’ll detail what we’re using instead.
  • Thin, light controllers. We refactor concepts mercilessly. It’s not just copy-paste duplication that kills – it’s pattern/concept duplication too.
  • No magic strings. Anywhere. No strings referring to controllers/actions/properties/anything that “actually” represents a type. We get 90% of the way there from MVC proper, and the rest comes from MVC futures (expression-based URL generation, including parameter evaluation)
  • Validation on your edit model  – not your domain model. Unless your app is CRUD, having edit models represent activities/operations/commands and attaching validation to those is a big win. We’re using FluentValidation right now for that – more on that in a future post
  • Smart HTML generation. Using metadata – not the weird ModelMetadata, but type metadata to generate HTML. Testing for existence of validation attributes, getting values out of the attribute, and using that to display a jQuery mask. More on that soon.
  • Vertical slice testing by modeling via queries and commands. I don’t always go all the way up to the UI, but by modeling commands and queries explicitly, we can isolate behavior into what really matters and not worry about ActionResults and the like in our tests.
  • Child actions are your friend. Don’t smash too much into a single model, don’t use dictionary-based ViewData access etc. Don’t alter ViewData from an action filter, use a child action. If you use an action filter/ViewData approach, you basically give up the ability to cache automatically.
  • Template generation from metadata. FubuMVC has a great example of this – using model metadata to generate the JS templates. If you’re altering CSS classes manually (class=”datepicker”) you’re doing something wrong. Don’t make me think, you have the information in metadata, use it!
  • AutoMapper – we use it pretty extensively still. We’re starting to use reverse mapping for simple cases (which now has some support out of the box). What we’re not doing is ignoring what SQL is getting spit out on the other side. AutoMapper and lazy loading can be a hazardous combination – but honestly no more so than not using it.

Things that didn’t stand the test of time:

  • Subcontrollers, and to a much lesser extent, portable areas. Not bad ideas, but better solutions came along (child actions and NuGet)
  • Customizing pipeline in the action results. We had a project where we really, really wanted Fubu MVC’s concept of behavior pipelines. Limit what actually happens in the ActionResult’s ExecuteResult method. It should be simple. We switched to a mediator pattern, and our lives improved
  • Model binding that hits a database. Your controller action takes a domain object, bound automatically from the GUID passed in. It’s not composable, customizable and so on. Instead, a Query object works a lot better and plays nicely with your existing toolbelt.

That’s the short list at least. I want to go into more detail on some tooling choice changes, but that’ll wait until the next few posts.

What you don’t see here is any JavaScript stuff – to be honest, 4 years away from JS is a LONG LONG LONG time. This app isn’t JS-heavy, so I’m really not going to say anything one way or the other.

What’s on your list for how you’ve changed how you build MVC applications since the release of MVC 2?

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in ASPNETMVC. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Can you write a small example application using your pipeline and push it github? I’ve been trying to find an optimized way to get started on a big application but I don’t have enough experience to build my own. I’m sure your way will be helpful.

  • Suhas Chatekar

    “Mvc Proper” and “MVC futures, are those some kind of libraries or I’m being dumb not to understand what you are saying?

    • jbogard

      Nah – MVC Futures is another MS MVC assembly, but for things not in the main, supported assembly. It’s sort of a proving ground for core ideas before making it in to the main System.Web.Mvc assembly.

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1401()

  • It would be great to see all those concepts in example/blog post.

    We have adopted CQRS quite heavily and enjoying it big time with separated validators for commands. All very testable and easy to write.

  • Callum Vass

    So are you using FubuMVC then? Or ASP.NET MVC?

  • Definitely the 1:1 pattern. I’ve moved to FubuMVC for the past couple years, but still have a couple MVC applications floating around, and that just makes things simpler.

    I also use conditional filtering ( to get somewhat of a behavior chain … obviously not as flexible as Fubu’s. But it works for what I want it to do.

  • Raif

    Hey, I would be very interested in seeing a post on Vertical Slice Testing and On Children are your friends.

  • Pingback: How we do MVC – 4 years later | Jimmy Bog...()

  • Pingback: ASP.NET MVC – 4 years later (in 2013) | Wake Up And Code!()

  • Shahed C

    Great writeup. I referenced your blog post in my blog, hope that’s ok. :-)

  • Thiago Silva

    I would love to see a complete sample MVC app applying all of these concepts. You could then use it as the reference code for your next blog posts, instead of just writing single line code snippets. Is this a possibility?

    • jbogard

      Yeah, next time I do a talk on MVC I’ll have a sample that shows this stuff.

  • I love looking on the internet and use a variety of tools, one would be best, I would use that.

  • shailendra

    nice and great job , useful information, It helped me to understand concept

  • Pingback: Put your controllers on a diet: redux | Jimmy Bogard's Blog()

  • Rafael

    About the validation on the edit view model, don’t you get any problem with duplicate validation code?

  • Pingback: Survey of two large MVC projects | Jimmy Bogard's Blog()

  • Brutus Maximus

    so 3 years later, what’s the deal with how you do mvc ? I’ve been following a similar path.