I recently started work on an MVC project, and now it seems that every 5 minutes I come across big turning design decisions about how I want to go with this thing. Always so, right?
I decided to completely exclude domain class classes from Views; this will lead to a lot of similar ViewModels models, but using AutoMapper I don't think this will be a problem, and I think this is a good clean approach.
However, my last debate surrounds the display logic. Let's say I have a MyData model with a property of type Status . This listing is as below:
public enum Status { Ok, NotTooGreat, CouldBeBetter, Awful }
In the view, when I render this model, I would like to display the status and additionally color the output depending on how bad the situation is. for example, If it is Ok , I will show green if it is NotTooGreat or CouldBeBetter than yellow, otherwise red for Awful .
Where should this logic live? Ultimately, the color selection itself will be in the view (for example, determine which css class to output, this class controls the color), but determining what the state is is a solution that I suppose should not be in the view . Possible options:
Use DataAnnotations in a custom ViewModel class, e.g.
public class MyDataViewModel { public StatusViewModel Status; } public enum StatusViewModel { [StatusDisplay(DisplayState.Ok)] Ok, [StatusDisplay(DisplayState.Warning)] NotTooGreat, [StatusDisplay(DisplayState.Warning)] CouldBeBetter, [StatusDisplay(DisplayState.Error)] Awful }
This means that my mapping is pretty stupid and can just display enumerations by value. View will then rely on the HtmlHelper to change the output according to the DataAnnotation. It looks pretty straight forward, but is there really too much “business logic” in the ViewModel? However, is this not just a problem with the user interface, so it is entirely possible for the ViewModel to determine what the display state is? Can I end up with a ton of custom DataAnnotations this way? Can they not inflate if I also need to indicate what actions the user can perform in accordance with the current state?
Keep the ViewModel simple and rely on the Mapping code to host the logic:
public class MyDataViewModel { public string StatusText; public DisplayState Status; }
This means that the ViewModel does not know what state is tied to what is displayed in the DisplayState, it just knows what different DisplayStates can be (for example, Ok, Warning or Error). However, this requires that the logic then sit in the display code, which does not look like a “match” with me - until now, the cards between Model + ViewModel have been fairly straightforward controller calls, but perhaps this was an extra fear?
It should be in the view, the ViewModel should remain the same as the Model, and then some code in the view or in the HtmlHelper, because it will decide which class to output based on what Status .
I think I tend to number 1, but I would appreciate the opinions of others. One thing that comes to mind is that this is a fairly simple example, but what if the view was much more complicated? Say, if MyData has the status Ok , do we want to display many more properties from the MyData model for the user, or display data from other classes of the model too?