View Models in ASP.NET MVC


Q: Should I have a view Model in my ASP.NET MVC architecture?


A: Yes.


Well, that was a short post! J


Being more serious, this is an interesting topic that the advisors and p&p team discussed a few times while they were building the Reference Implementation for the soon-to-be-complete Web Client Guidance, and it is something I’ve heard discussed time and time again out in the field.


I usually describe the “M” in both MVC and MVP as “the rest of the application”, i.e. the business logic and business entities, and implicitly everything below in the stack. Some people don’t like this analogy, saying the “M” refers only to the classes used to pass data between Controller and View. I agree it is arguably inaccurate, but I find it a useful way to think about a design based on these patterns… not least because of some of the variations in design I’ve seen that reflect those described below.


Where discussion gets interesting is when people start asking what the View can depend upon (and for the rest of this post think MVC, not MVP). To dodge a lot of detail this comes down to the following options;


1.       Business Entities are passed to a View as the “Model”. Therefore the View has detailed knowledge of part of the business layer.


2.       Business Entities are never passed to a View – instead the relevant data is extracted and placed in a new entity reserved purely for use by the UI layer… or a “View Model” as people call it today (back when I coded as a day job we called these UI Entities so don’t go thinking this is something new!)


These options become particularly interesting when you consider that in many modern systems the Business Entities are actually basically Data Transfer Objects generated or consumed by a tool such as the Entity Framework, nHibernate, etc, etc. This is useful because they may have validation behaviour built in. Business Logic is usually implemented as POCOs that manipulate, create, or return these DTOs.


This means that in option 1 the UI has access to all the validation goodness that exists on these entities. What’s more, you don’t need to create a new set of View Models that almost exactly match your data layer, and a set of “mappers” that convert Business Entities into a View Model.


However… note that I said “… almost exactly match…”. You see, in the vast majority of systems there is something other than just what is stored in your database that needs passing to the view. This could be the current user’s login name, or the current date and time. Or perhaps we must pass Boolean flags to indicate whether or not various regions of the screen should be displayed based on the user’s roles.


To illustrate the differences, let’s see 3 different examples as to how you might pass model data to a view. I’ve blatantly plagiarised some of the great comments that Francis, Julian, and the advisors made here so don’t credit me with all the hard work J


Variant 1: No View Model


In Variant 1 we have no View Model at all, so our controller simply retrieves data from the business logic as a business entity, and passes it to the view…


public class ModelController : Controller


{


    public ActionResult Index(int someparameter)


    {


        BusinessEntity model = BusinessLogic.GetModel(someparameter);


        return View(model);


    }


}


The code for this is simple, concise, and requires very little work on my part. However, what if I want to add a property to indicate whether or not the “login” region of the view should be rendered? What if the view needs some other model data? This approach very tightly couples not only the business logic to the UI, but potentially the database to the UI (depending on your ORM tool, and how your business entities are created).


To summarise;


1.       (con) This approach is unlikely to suit real MVC applications, as there is usually additional data that must be passed across.


2.       (con) It is not flexible – it is more likely to lead to additional code churn after go-live other than in the simplest of cases.


3.       (con) Developers that don’t know these patterns well may consider adding UI-focused fields to your business entity, which compromises your business layer.


4.       (pro) MVC can take advantage of the same validation mark-up attributes (or other scheme) that your business layer uses.


5.       You can use it, but be prepared to take the hit for changes later, and make sure your developers know how to evolve it into Variants 2 or 3.


The bottom line is that I would use this if I knew it was very unlikely that the view (perhaps a very focused partial view in a very simple system) would ever need more than a single business entity… but other people, including the p&p guys, rightly have strong concerns about this approach.


Variant 2: Container View Model


In Variant 1 we saw how little code was needed for the simple case, but there are warnings about the inflexibility and risk to the integrity of the business layer. Variant 2 aims to maximise the benefits of Variant 1, whilst minimising the code you must hand-crank by using a simple View Model container to pass multiple business entities (and potentially other types) to the view…


public class ModelController : Controller


{


    public ActionResult Index(int someparameter)


    {


        BusinessEntity model =


            BusinessLogic.GetModel(someparameter);


        OtherBusinessEntity othermodel =


            BusinessLogic.GetOtherModel(someparameter, model);


 


        ViewModelContainer container = new ViewModelContainer


        {


            ShowLogin = !User.Identity.IsAuthenticated,


            LoggedInName = User.Identity.Name ?? “”,


            TheEntity = model,


            AnotherEntity = othermodel


        };


 


        return View(container);


    }


}


 


public class ViewModelContainer


{


    public bool ShowLogin { get; set; }


    public string LoggedInName { get; set; }


    public BusinessEntity TheEntity { get; set; }


    public OtherBusinessEntity AnotherEntity { get; set; }


}


Here we have the “ViewModelContainer” class, that is designed to carry our payload of a couple of business entities and some other primitives. Our Controller is responsible for fetching the business entities and then assembling this container, before passing it to the view.


So let’s think about our pro’s and con’s;


1.       (pro) Any data not contained in our business entities can easily be passed across.


2.       (pro) Change is easy to handle when it consists of additive data.


3.       (pro) Developers will most likely add UI fields to the View Model container, not to the business entity.


4.       (pro) MVC can take advantage of the same validation mark-up attributes (or other scheme) that your business layer uses.


5.       (con) But… your business entities must still match the precise requirements of your view. If you want to convert or translate internal system concepts into something easier to display, this is difficult using this model.


Overall, this is my personal favourite as it provides flexibility and future proofing for little extra effort over and above Variant 1. However, it is by no means perfect and you must be willing to consider replacing your business entities with custom View Model entities if the needs of UI and business layer diverge… i.e. convert to Variant 3.


Variant 3: View Model and Mappers


Variant 3 is what could be called the utopia practice, in that it ensures your business and UI layers are suitably separated, with “mapper” classes (often referred to as the “Entity Translation” pattern) marshalling the relationship between the two. However, it comes at a price – and that is a little coding effort.


Let’s see how this looks;


public class ModelController : Controller


{


    public ActionResult Index(int someparameter)


    {


        BusinessEntity entity = BusinessLogic.GetModel(someparameter);


        MyEntityViewModel model =


            MyEntityViewModelMapper.ConvertFromBusinessEntity(entity);


       


        return View(model);


    }


}


 


public class MyEntityViewModel


{


    public bool ShowLogin { get; set; }


    public string LoggedInName { get; set; }


    public string Name { get; set; }


    public bool IsOver18 { get; set; }


}


 


public class BusinessEntity


{


    public string Name { get; set; }


    public int Age{ get; set; }


}


This time I’ve showed the BusinessEntity class too so that you can see how it differs from the View Model. We can see that the Controller fetches this entity and then uses a mapper class to convert it to the View Model class. This mapper might also access environmental variables (e.g. User.Identity) or I might pass in other data.


The point with this approach is that the business entities are never passed to the view – only View Model classes can be consumed by views. This leads us to some findings;


1.       (pro) Any data not contained in our business entities can easily be passed across.


2.       (pro) Change is easy to handle when it consists of data that should be added, removed (or not displayed), or even altered / mapped (such as our Age field).


3.       (pro) Developers will add UI fields to the View Model, not to the business entity.


4.       (pro) The UI’s needs are kept distinct from that of the business logic.


5.       (con) But… MVC cannot take advantage of the same validation mark-up attributes (or other scheme) that your business layer uses. Instead you must duplicate this.


Conclusion


The great news is that the p&p Web Client Guidance Reference Implementation includes some great examples of Variant 3. Check out the SongDetailsViewModel, and the Mapper classes. It quickly becomes clear how much freedom this separation of concerns gives us, and how easy to follow the pattern becomes when you use it as a convention.


Hopefully the Variants above help you understand why this approach was chosen, and help you pick an approach yourself. Make sure you check out the Reference Implementation to see how this can work in practice.


 

Comments (41)

  1. Julian says:

    Very well put! I like how you explain this as an evolving process when you start with a simple view. I’d only suggest variant 1 if and only if the whole team is willing to make the jump to the other variants when needed. Updating the business entities because of your UI is too big a risk if this is not an identified risk.

  2. Colin Jack says:

    I don’t agree at all about DTOs and POCOs, its behavioral domain models that predominate most of the discussion you’ll find.

    One other point I’d make, if you go for option 3 you have a definition of how to map from the domain model to the view model. If you can then access metadata that describes what rules to apply to particular properties on the domain AND if you have tool like PostSharp then you have the option to copy/map the rules from the domain onto the view model as part of the build.

    Its tricksy code, and gets very hard when the rules are attributes, but it is basically possible and I can provide a code sample showing it if it is useful.

  3. simonince says:

    @ Colin,

    interesting points.

    I agree that a lot of discussion is out there about domain models, but I don’t think that is a true reflection of how most people write systems… but rather it’s a smaller minority that happen to be vocal. I’m more than happy to be wrong here though as I don’t think one or the other is a clear winner; it depends on the scenario.

    Also, I completely agree about copying rules to View Models – I had this tooling approach in the back of my mind when I wrote the text above but I guess that isn’t clear. If you do blog any code about how you’ve done that I’d love to see a link so feel free to post here :-)

    Thanks,

    Simon

  4. Colin Jack says:

    @simonince

    Vocal, yes. They’re also the small group thats influenced key technologies including ASP.NET MVC and EF. It does depend on your scenario, but I think too many people make uninformed decisions based just on what the latest Microsoft tooling offers, and I don’t think thats the way modern systems should be developed.

    Most people who use domain models also realize that they aren’t always the best option, but many people who use DTO based business logic don’t seem to know enough about the alternatives for my liking.

    I can definitely put together some of the code and e-mail it to you, it definitely seemed a workable option but it’d need further development. In particular it worked for code-based rules and for attributes with no arguments. Anyway I’ll send you something in the next week or two if you’re interested.

  5. Craig Stuntz says:

    1) You can use projection instead of mapping to project EF entities onto view models.

    2) View models often have different validation rules than EF entities, since non-UI layers may provide some of the inputs after the user.

  6. simonince says:

    Hi Colin,

    Some good points… and some long running debates :-)

    I’d love to see a blog post on how you’ve done that! It’s easy to digest that way, and time is money, as they say!

    Hi Craig,

    1) I agree, but fundamentally that is still mapping… just using a funky technology. It also depends on the rest of your architecture – your View Model and EF context might be many layers apart!

    2) That’s a very interesting comment… it "feels right" to me, but then the more I think about it I’m not so sure… you see if I can possibly push any validation up from the database or business layer all the way to the browser client (and repeat it server side of course!) then I will. That means that if the field is displayed on the screen and it has validation, I want to "push it up the architecture stack".

    What I think you’re probably referring to is what I meant by;

    "…your business entities must still match the precise requirements of your view…"

    … when I was discussing Variant 2. If the EF entity doesn’t match your needs for the UI, you should probably be using Variant 3. Does that make sense?

    Or have I misunderstood?

    Cheers,

    Simon

  7. Craig Stuntz says:

    Well, I’m of the opinion that one should nearly always use "Variant 3" anyway.

    Regarding #2, consider the following. Imagine a system which collects timecards for employees. Employees are permitted to fill in a start time and a stop time, in which case the system will calculate elapsed time for them, or to fill in and elapsed time without a start time and a stop time. Timecards are represented at the Entity Framework by the type TimecardEntity, and at the UI level by the type TimecardPresentation.

    At the TimecardEntity level, it certainly makes sense to have the ElapsedTime property be required. Whether or not the user fills it in directly, it must be present before the entity can be persisted to the database. On the other hand, StartTime and StopTime are not required.

    The user interface’s validation rules are different. The user must fill in either StartTime and StopTime (in which case, any value for ElapsedTime would be ignored and replaced with a calculated value by the system) or just the ElapsedTime. So it does not make sense to make ElapsedTime required, but it does make sense to validate that either ElapsedTime or both StartTime on TimecardPresentation are filled in.

    Validations, of course, are not the only thing which can vary. Other attributes you might put on your presentation model, like Description could be different if the same Entity Framework data might be displayed on two different user interfaces, via two different presentation models.

  8. Nikolay Iliev says:

    I would add a radical view on this topic. Lets consider Variant 4 – "No Domain Model". Or in other words "Only View Model".

    (pro) – maintain only one domain model (the model defined in the database). No need to maintain artificial abstraction layer of classes having exactly the same structure as the tables in the database.

    (pro) – higher performance and scalability. We need to show a list with 3 columns – lets extract only the data for these columns and fill the appropriate view model objects with these 3 properties, instead of pulling all data for all 20 properties/fields in our domain model and show only 3 of them. Less data reads, less internal network usage, less memory usage, faster UI response time and better scalability.

    (con) – duplication of the validation markup and/or validation methods (for more complex validation scenarios)

    Just to clarify – by "No Domain Model" I don’t mean direct database access in the UI with no abstraction between. What I mean is to model in the middleware objects suitable for the consumer layer (in this case the UI) instead of recreating the database model.

    There are scenarios where the duplicated domain model is usefull (when an API has to be provided for integration with third party systems and the exact data usage is not specified – i.e. it is not possible to define view models in advance), but when considering a common web based application, its API is only by itself.

  9. simonince says:

    Craig;

    All good points; any system that has these kinds of complexities is a very strong contender for Variant 3, and that’s why the p&p guys went with that approach in their guidance.

    Hi Nikolay,

    you make an interesting point. I must admit I initially thought "what?!" but then I read through your comment again and I see what you’re saying.

    I think it’s basically very similar to the age old discussion about whether or not data access classes should represent a database table or the needs of the UI. I forget the pattern names but this has been a huge discussion on and off in various forms.

    To be honest I think modern ORM tools mean that you can do what you describe using a framework like nHibernate or the EF, mapping just the database fields you need for the UI, and then use Variant 2 of my approaches above… this gives a very close approximation of what you describe. I also probably wouldn’t recommend this for performance reasons; in reality most "average" systems have much bigger and more serious bottlenecks, and a well structured, clearly coded system is far more likely to be maintainable, and IMHO to perform well.

    Good spot on the forgotten variant though :-)

    Simon

  10. Nikolay Iliev says:

    Most of the O/R mapping frameworks support lazy loading, but its efficiency compared to explicit and selective data loading is another story.

    It is clear that for many systems the performance and scalability are rarely the biggest problem. This is especially true for enterprise level solutions usually accessed by a small number of internal users.

    As you said the maintainability is one of the most important aspects and in such cases it is usually priority #1.

    The number of view model entities is much higher than the number of domain model entities, so if one wants less maintenance overhead, probably the best balance is provided by the hybrid solution (Variant 2: Container View Model) – no need to create and maintain explicit view models, but still having the ability to add view specific information without breaking the domain model integrity.

  11. Joe Wilson says:

    This is a really nice walk through the ways to get a model up to the view.  I tried Variant 2 for a while, thinking views composed of business entities plus anything extra was the best way to go.  But I had properties and methods in my business entities I really didn’t want the view going near.

    They really are separate concerns.  They may overlap a lot, but they ultimately serve different purposes.

    So I’m all about Variant 3 these days with AutoMapper to make the conversions easier.  I also think one view model per view will become more valuable with the new html helpers in MVC2 that spit out your entire view model for display/edit.

    It does seem like the last mile on Variant 3 is getting centralized validation rules from the business domain up to the view model so your controller can take advantage of the model binder validating for you.

    I’m just decorating my view models with the Data Annotations attributes and living with that for now.

  12. simonince says:

    Nikolay;

    good comments – thanks for the thoughts. I’d be interested to hear what others think to your perspective…

    Simon

  13. Craig Stuntz says:

    Nikolay,

    When you project from an EF context onto a presentation model, the EF does *not* materialize full objects. In other words, if I do:

       from e in Context.Entities

       where e.Id == id

       select new

       {

           Name = e.Name,

           ChildName = e.Child.Name,

           GrandchildName = e.Child.Child.Name

       }

    …then only three columns are returned from the DB, not every column for every entity. I realize many ORMs don’t work that way, but it’s a limit of that ORM, not a reason to avoid ORMs in general.

  14. simonince says:

    @ Joe,

    Thanks! I think your story sounds very reasonable; there are many cases where you just have to go with Variant 3, and there’s no doubt it’s the "grown up" solution.

    Simon

  15. Nikolay Iliev says:

    Simon,

    I also would like to thank you for this article; it is well structured and very helpful. Now I have kind of a dictionary of the modelling options, so even the the conversation inside my head is much easier when thinking on the topic.

    There is something that could be added as a pro for variants 2 and 3 (having view models): no security concerns regarding automatic model binding – when a view model is used there is no chance for the hacker to update data in fields not supposed to be updated (role, user rights etc.). The exclusion from binding works, but what happens when somebody adds properties to the entities in the domain model and forgets to go and add some or all of them to the list of excluded properties for binding.

    Nikolay

  16. Nikolay Iliev says:

    Craig,

    It is not about pros and cons of ORM’s and how efficient they are, but about view vs domain model.

    In your example the code fills a view model with data from the domain model. If it was not using an OR mapper, the domain model would not be really needed as the knowledge about it would be capsulated in the stored procedure or the adhoc SQL query.

    One more thing to add on the view model vs. domain model. The validation rules specified in the domain model are general and assume full object validation, so no rules like "if this is a new customer, we want only to have his/her email and password, but if he is updating his own profile the first and last name are mandatory".

    The partial data entry interfaces (wizards) also have a problem with this full validation specified on domain model level – step one of the wizard asks for some of the data and it has to be validated before going to step two, but the domain model validations could consider the object invalid at the first step as other required fields are empty (they are supposed to be supplied at step 4 for example).

    Maybe some kind of a validation category (ApplyOnCreate, ApplyOnUpdate, ApplyOnStep1 etc.) could be added to the data annotations and implemented in the custom validation methods to solve this problem.

    Another issue with the domain models is easily visible with the simple user registration/creation scenario – enter a password and repeat the password. Is the repeated password part of the domain model – no, but how to deal with it from modelling perspective.

    Nikolay

  17. Mehdi Khalili says:

    Simon

    Good post. I think there is a forth (or I should say fifth) variation: (a variation of) CQRS.  

    So if we were to take your third variation one step further, we would get View Model directly from whatever the controller is calling into (it being BusinessLogic class or application service or database through an ORM!!). That way you can share your validation logic on the server and client, because you are basically using the same class and your class is very view specific so it shares all the pros with your third variation.

    It also has some other added benefits; for example,

    there is no mapping whatsoever. View Models are stored in database as tables; so your view model is a OO representation of your table (or actually it is the other way around: your table is a database representation of your view model :o))

    But is it not what Nikolay explained above? To some extent except that Nikolay thinks there should not be a domain model: only VM is required. I believe domain model is required, because VM is like a DTO with some little (mostly validation) logic, but where does all that complicated business logic go? It goes into the domain model.

    Here is how Udi explains it:

    http://www.udidahan.com/2009/12/09/clarified-cqrs/

    I think some variation of what Udi explains fits easily into a lot of applications.

    Mehdi

  18. Nikolay Iliev says:

    Mehdi

    Thanks for the link to this interesting article.

    In my opinion the business logic has to be placed in its own domain, otherwise we add to much dependencies.

    If we have an entity "Seller" and there is a business logic doing a check for VAT number validity through an external service, sending email notifications to account managers for newly registered seller etc., do we place this business logic in the domain objects and make them dependant on the VAT service objects and email notification objects?

    I would prefer to have only internal dependencies inside the domain model and place the orchestration in explicit business logic objects using the domain model, the external services etc.

    The reality is that most of the domain objects are more or less pure DTO’s serving as a memory storage for the data comming from the RDBMS with some validation added and as such I don’t like their presence if I have to build another layer of abstraction on top of them so it can serve the views in the application.

    I dont like them, but I usually have a domain model in the middleware as there are too many simple use cases (probably 80% of entities), where the domain model entities can be directly used as view model entities and there is no need to add and maintain additional level of abstraction (view models). However, as all definitions are abstract, we could say that the domain model entities in such cases are actually view models as they perfectly serve the application views.

    Don’t get me wrong, I am defending the "view model only" approach only to get more feedback on this concept. The reality is that every architecture depends on the requirements and the project constraints.

    Building a small system for intranet usage could be done in many ways (less concerns on performance/scalability, more on maintainability and time to develop/price), while building an application accessed by a large number of users over internet requires a different approach (more careful approach to memory consumption, efficient data access and modification patterns, caching etc.).

    Nikolay

  19. Mehdi says:

    Nokolay,

    I agree with almost everything you said; there are just a few minor things as follows:

    – Domain Models are not DTOs unless you are using anemic domain model in which case you do not really have domain model. This is how Microsoft promoted the use of EF1.

    – I would not put validation on my domain model except for invariants. Validation is to be done on the user input based on the context. So validation on the "same data" on one context could be different on a different context.

    At the end, I am honestly not quite sure if there should be a default architecture for all applications or architecture should be based on the requirements!!!! Please read my comments at the end of the following post to understand what I mean: http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/01/26/context-and-best-practices.aspx?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+GrabBagOfT+(Jimmy+Bogard)&utm_content=Google+Reader

    @Simon: I am sorry for putting these here~~

    Mehdi

  20. Great discussion taking place here! I’m following it with great interest.

    Two problems with alternative 3 is class explosion, for every business entity you have to 2 more classes, one viewmodel and one editmodel. for a semi simple application that is 60 classes..

    Another is mapping from editmodel to businessmodel, the Automapper creators says Automapper should be used for that, but don’t give us any advise on how to do it correctly. Hand wire?

  21. simonince says:

    @ Carl,

    I completely agree Variant 3 requires additional effort, although I think you’re quoting a worst case… but this is always a game of balancing trade-offs. I guess this post is intended to help people make the decision as to which is right for them. I’m not a believer in there being one correct approach.

    The popularity of automapper is interesting too… thanks for the comments!

    Simon

  22. Joel P says:

    I keep hearing good things about AutoMapper and yesterday it went 1.0. Seems like we all ought to give it a serious look.

  23. Nikolay Iliev says:

    Just did a quick test with two classes having 10 properties each – for 1M objects the handwritten data copy took 166ms, while the automapper needed 21268ms. This is a difference of 128 times (not percentages).

    Would it be a bottleneck – no, at least in an average application, but the maintainability aspect is also not black & white.

    The automapper would handle newly added properties to both classes (if they have the same names), but if one changes a property name only in the source or the target the automapper would be unaware of the change and there will be data lost, while a handwritten mapping source code would mean either a compiler error or automatically renamed field in the mapping code using the refactoring tools in VS.

  24. Rob White says:

    I’m curious, but would this be a valid viewmodel?

    public class ViewModelContainer<TEntity, TSecondEntity>

    {

       public bool ShowLogin { get; set; }

       public string LoggedInName { get; set; }

       public TEntity TheEntity { get; set; }

       public TSecondEntity AnotherEntity { get; set; }

    }

    I’m just thinking this may be naive, but it seems to keep things a bit more, well generic.

  25. simonince says:

    @ Rob,

    technically, yes… but if you’re aiming for Variant 3 the problem with your approach is that you don’t have a separate model for each View. Instead, I’d probably create a base abstract ViewModel class and inherit from it if I needed to reuse properties.

    Otherwise change might affect multiple screens, as developers will add UI fields to the generic View Model. All the Views’ needs become entangled which would concern me.

    What do you think?

    Simon

  26. Rob White says:

    @Simon

    Yeah, I agree, what is was driving at was not using base classes for your entities. In a more real world scenario you’d defiantly need to be more careful about what goes into a base view model container.

  27. Virshu says:

    Please remove if it's a duplicate…

    *********************

    This thread has been dormant for several months – but it contains the best list of options, and it has one radical proposal already; so I'll throw one of my own… In vast majority of cases I don't see a reason for View Model; basing a view on domain model is just fine.

    Let me qualify a few things… First, I am talking specifically about "input" views (Edit or Create) – not about Display views (List or Details). Second, there are exceptions (timesheet may be a good example) – where View Model is significantly different from domain model – in my experience this amounts for 20 per cent of cases at most. Third, if in the future ASP.NET MVC will have something like UpdateModel(DomainModel m, ViewModel vm) that will automagically update matching fields – I will be happy to rethink this radical statement. AutoMapper is probably a step in that direction.

    @Simon, you advocate Variant 2 which is essentially a "union" of two business entities and some unrelated data. In your example it's login information that is usually orthogonal to the view, and is better presented in partial control. The example of two business (domain) entities that I can think of is Order Header (read-only on the page) and Order Details (Input). Again, having Order Details – maybe through RednerPartial() – based on domain model seems easier to develop and to maintain. So, Variant 2 becomes Variant 1 all by itself.

    The obvious two benefits are that you can leverage DataAnnotations from the model – both in display and validation. The downside… again – my experience that in 80 percent of the cases ("edit customer" or "create new order") there seems to be no downside.

    For the record, I've done MVC programming in PHP for about 5 years now; and I am managing an ASP.NET MVC project for the last year. I've read a lot of posts (including from people whose opinion I take as gospel) that advocate Variant 3 ("always use View Models") – so it took me a lot of thinking to come to this heretical conclusion…

  28. Jon says:

    This article just made MVC click for me.  I've been tinkering around with it for a while and just failed to fully realize how to make the webforms side of my brain "get it".   This article, and specifically variant 3 just made that happen!

    Thanks,

    Jon

  29. simonince says:

    @ Felix –

    I think you're entitled to that preference, as long as you're explicitly making that choice. I'd just say "if you need to move up to variant 2 or 3, do so rather than hacking your domain entities". If you're happy with your team all following that guidance, fair enough!

    I still believe in variant 2 as the starting point, moving to variant 3 if needed. I find it's the best balance of risk traded against development effort.

    Simon

    @ Jon –

    very pleased to hear that! Thanks for the feedback.

    Simon

  30. Cesar says:

    The best scenario is Variant 2 with only one ViewModel (the business entities). But that rarely happens.

    I would go to Variant 3 but, what happens when you want to reuse a ViewModel like MenuViewModel.

    Would you repeat the properties for each implementation of the menu?

    Where would you place the translation methods? In a helper? in a class for each ViewModel? in a class just for the MenuViewModel?

    Already 3 months that I left web forms and still missing re-usability  in MVC

  31. simonince says:

    @ Cesar,

    I'd normally expect the menu to be encapsulated in a Partial View of some description, so you'd just have a single MenuViewModel that is paired with that View (I usually recommend each ViewModel class is "owned" by one View, with some exceptions). Therefore, I don't see a problem here?

    As for mapping methods, if doing it the manual way I would create a class per source or destination type, depending upon your preference… although I'd prefer an automated solution like AutoMapper.

    I think reuse is actually better in MVC, it just takes a bit of getting your head around, so I understand your pain. Perhaps I'll blog on that sometime.

    Hope that helps!

    Simon

  32. thangchung says:

    @Simonince: Good articles, man. I approached same with Variant 2 and a little bit with Variant 3. I have built ViewModelContainer and using AutoMapper for mapping between my DTOs from WCF service to ViewModel.

  33. simonince says:

    Thanks thangchung! Great to hear you're getting on well with it.

  34. kapil saxena says:

    hello, i like your views they are very good. i like to visit your site again thanks.

     

  35. simonince says:

    @ Kapil;

    thanks! Pleased you find it useful.

    Simon

  36. Andrei Rinea says:

    There is a downside to variant 2 that hasn't been mentioned : the risk of exposing sensitive information in the view

  37. simonince says:

    @ Andrei,

    excellent point! I do call this out in conversation but you're right it isn't clear above.

    Simon

  38. David Fauber says:

    "it comes at a price – and that is a little coding effort."

    If you use Automapper here, its very little coding effort (and the way that I prefer)

    Good article, thanks for posting it.

  39. simonince says:

    @David,

    I totally agree… although that of course may have a tiny perf impact. Nothing comes for free, but I personally love AutoMapper. I have worked with teams that love it and teams that would rather hand-crank the code though… so I'm not too prescriptive.

    Simon

  40. nomesaki says:

    The great news is that the p&p Web Client Guidance Reference Implementation includes some great examples of Variant 3. Check out the SongDetailsViewModel, and the Mapper classes. It quickly becomes clear how much freedom this separation of concerns gives us, and how easy to follow the pattern becomes when you use it as a convention.

  41. Tarek B. Juneed says:

    i liked what i read, it was very clear and subjective

    thank you Simon