0

I am creating some view models for my ASP MVC web app. I created "code first" models for database. Is it a good way to derive view models from database models?

Example database model:

public class Project
{
    [Key]
    public int Id { get; set; }
    public int? CustomerId { get; set; }   
    public int TypeId { get; set; }   
    public string Number { get; set; }  
    public string Name { get; set; }
}

View model:

public class ViewModelProject : Project
{
    [NotMapped]
    public DateTime? Start { get; set; }
    [NotMapped]
    public DateTime? End { get; set; }
    [NotMapped]
    public string Manager { get; set; }
}

Is this the right way or is it completely false?

EDIT (subquestion): I have some very simple database models like ProjectType, which only contains i.e. two properties. Should I also fragment those models in model view or can I make it that way: Simple database model:

public class ProjectType
{
    [Key]        
    public int Id { get; set; }    
    public string Name { get; set; }
    public int? Code { get; set; } 
}

Can I use it like so:

public class ProjectVM
{
    public string Name { get; set; }
    public int Number { get; set; }
    public ProjectType Type { get; set; }
}

Or does it have to be fragmented like so:

public class ProjectVM

    {
        public string Name { get; set; }
        public int Number { get; set; }
        public string Type { get; set; }
        public int TypeCode { get; set; }
    }
gtu
  • 707
  • 1
  • 10
  • 22
  • No its not the right way - [What is ViewModel in MVC?](https://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) –  Sep 13 '17 at 06:59
  • Totally wrong as I think. The viewmodel should have associated with the data model - even not all data model fields included (depending on view page you're using). – Tetsuya Yamamoto Sep 13 '17 at 07:05
  • But sometimes it seems so straightforward to use it like so. So I need to "rewrite" every model to Viewmodel every time? – gtu Sep 13 '17 at 07:13
  • The purpose of using a view model includes separation of concerns, protection against over and under posting attacks, ability to add view specific attributes which are not appropriate on data models, etc - what you doing defeats the purpose. And asking for opinions is off-topic. –  Sep 13 '17 at 07:16
  • Ok, I see the point now. I just added a subquestion, because I am not sure about that also. – gtu Sep 13 '17 at 07:42
  • 1
    The "subquestion" is unrelated to the original question. You should open a new Q&A for that. – Sefe Sep 13 '17 at 07:46
  • I think that it is the same problem, just different point of view. Relating to what was written I assume that second example is the correct one. – gtu Sep 13 '17 at 10:32

1 Answers1

3

I would not recommend doing it this way. I (and many others) have tried it and it doesn't work well. You will inadvertedly run into troubles, since an MVC model has to be tailored to the view and what you get from the DB rarely fits. Sure, you can hammer it into place, but the code quickly gets messy and store-related and UI code starts to mangle together. This even shows in your example, since you have to put the NotMappedAttribute (which is related to data storage), to ViewModelProject (a class at UI level).

There are many other examples to show this problem, but an especially good one I find when you want to serialize a model object to JSON and send it to a JavaScript client. The JSON serializer takes the values of all public properties and adds them to the JSON. If you want to exclude a property, you have to mark it with a ScriptIgnoreAttribute, which you would also have to apply to the base class, which breaks separation between UI and store-related code.

The better way to go is to keep the staorage model and the MVC model separated and to map the data from one to the other (there are already pre-existing frameworks that help you with that, such as Automapper). This comes with additional advantages, for example better testability, since you are now not dependent on a specific data store to create model instances.

Sefe
  • 13,731
  • 5
  • 42
  • 55