Skip to main content

A quick post on view model mapping

I had a question about options for mapping Umbraco content to view models come up today, and given my response in Slack was getting a bit long and I'm sure I'll need to refer to it again, decided to create a post instead.

So what follows is a quick summary of the history and options for adopting a pattern of mapping Umbraco content to a strongly typed view model. It's not intended to be fully comprehensive... am just saving my keystrokes.

Around the time of Umbraco 6 or 7, some colleagues and I from Zone released Umbraco Mapper, which used a combination of convention and configuration to allow for these mapping operations to be made in code. We used it in a fair few projects and liked the approach, and, judging from some feedback, a number of others from the Umbraco community did too.

Just after, though likely in use or development concurrently, was Ditto released by Lee Kelleher and Matt Brailsford. This did a similar job, and it gained a fair bit of traction in the community. It wasn't upgraded beyond Umbraco 7 though.

There were others too - UmbMapper being one that looked to be the best performant. Again though I don't believe it was available beyond Umbraco 7.

Likely part of the reason these packages weren't continued was because Umbraco themselves introduced models builder. This also solves problems in the same space, but isn't quite the same - the subtle difference being that it provides a strongly typed "content model" rather than a "view model". For some this may not be a big issue, for others, including me, there was still some value in having a tool to help map Umbraco content direct to a view model designed specifically to represent a single page (which may be similar to a single item of Umbraco content, but likely won't be exactly the same).

Alongside all of this of course is the well-known .NET library Automapper. However this doesn't know anything about Umbraco, so whilst it is useful for mapping between strongly typed models, it doesn't particularly help with mapping from Umbraco's IPublishedContent/IPublishedElement, without configuration for each individual property.

And it's probably worth mentioning you can still use strongly typed view models and not use a mapping library at all. You can see examples of this in the demo site that Dennis Adolfi blogged about here (such as in the code available here).

Now the story gets a bit (more?) confusing... as Umbraco introduced their own "UmbracoMapper" class in core. Which was fair enough, it's their name and I probably shouldn't have stepped on their trademark in the first place! It provides mapping between types, a bit like AutoMapper but more lightweight, and with less convention. It can be used in Umbraco implementations too, but as I say, it doesn't offer any convention based mapping nor be designed to work specifically with IPublishedContent/IPublishedElement.

For that reason, when it came to Umbraco 9, I decided to keep the original "Umbraco Mapper" going, but renamed it to Anaximapper to avoid confusion with the similarly named class in Umbraco itself. This is available from NuGet and supports Umbraco 9 and 10.

Although I'm now working for Umbraco, this remains a personal, open-source project and isn't something supported (or necessarily even recommended... but I don't think they object!) by Umbraco themselves. As I'm no longer working at an agency developing Umbraco sites, it's not something I use directly any more either. But I am happy to keep it updated and supported in a personal capacity, so if you like the approach and find it valuable, you are welcome to continue using it, and if you run into any problems, issues raised and PRs are welcome.

Comments

  1. Hey Andy I just wanted to say this was exactly what I needed, and only wish I had found this post a bit sooner. I really don't understand why something like this isn't a part of the new UmbracoMapper. Being able to automatically map an IPublishedContent to a custom model is how I like to do things. So thanks again. Cheers Tim

    ReplyDelete

Post a Comment