I note that in the context of ASP.NET Core, ASP.NET MVC (which is older and has been replaced by ASP.NET Core), Razor and Blazor, the term "model" is shorthand for "viewmodel". Do not confuse it with "Entity model class", which I believe you're referring to by "data class".
But do I need to be repeating the same properties for each new model?
Yes (with exceptions, such as when you're composing view-models)
Do the models need to inherit from User data class?
No, don't do that.
While two or more different types (classes) may share the same members that doesn't mean they represent the same "thing". In OOP, inheritance should only be used to represent an "is" relationship, not a "has" relationship, and especially not a "I'm-too-lazy-to-have-to-declare-all-of-my-members-again-argh" (though I am very guilty of that last one... ).
Unfortunately C# does not (yet) support mixins, which is the term used to describe the ability for an object-oriented language to have multiple distinct types with the same members without expressing any kind of actual relationship between those types.
(With the exception that C# 8.0 on .NET Core 3.0 supports _quasi-_mixins with Default Interface Implementation, but it has limitations compared to real mixins, for example I understand you can't use this approach to import operator-overloads, conversion operators, or constructors and I think there's some limitations w.r.t. virtual
members too - and I think it doesn't work at all with structs
(at least not without boxing, which is bad for performance)).
Is all of this specific to MVC pattern?
It's common to the MVC design in every web framework, really - not just ASP.NET Core or ASP.NET MVC, but MVC frameworks for Python, PHP, Ruby, etc.
How do the model class and the data class relate to each other in the actual implementation?
- Given a domain entity in your project (in this case, a "User"):
- The Entity ("data") class represents the object as a business object, as well as how it's stored in your database.
- Each single View-Model ("model") class represents a specific view of your business domain (which may be read-only or read-write) which is typically a snapshot of a subset of your business domain's object graph as well as containing additional properties for the page itself (such as the page
<title>
, the currently logged-in user's details, etc).
- Note that a single domain entity class can have more than one view-model class to represent it (see below). And similarly, a view-model can represent more than one domain entity object (or none at all).
For example:
- Given a
class User
(your entity class):
- A "User List" page will have
class UserListPageViewModel
with an IReadOnlyList<User>
property.
- An "Edit User" page will have a
class EditUserPageViewModel
with with properties for each editable user property/column/attribute.
- But it must not expose the
User
class for model-binding, because then an attacker could send a fake POST
form request that instructs the model-binder to overwrite the Password
field, for example.
- A "Welcome page" view-model may also contain a
public User CurrentUser { get; }
property which contains a loaded User
instance with information that a "layout" .cshtml
file (aka .master
"master page" in Aspx, or any kind of common HTML template, etc) will use to populate a "Welcome John Doe" area, etc.