Search code examples
.netasp.net-corewebblazorblazor-webassembly

What is difference between model class and data class?


I'm new to web development and I'm struggling to differentiate between a model class and a data class, specially when implementing them.

I found this question and I kind of understood the theory about it: the data class contains all the core information about an object and a model class only contains the information that needs to be exposed. So I can have a user data class like this:

public class User {
    public long Id { get; set; }

    public string Name { get; set; }

    public string Password { get; set; }

    public string Email { get; set; }

    public int Score { get; set; }
}

And a model class for the login page like this:

public class UserModel {
    [Required]
    public string Password { get; set; }

    [Required]
    [EmailAdress]
    public string Email { get; set; }
}

And I would have to create another model class for sign up, for example, adding the Name property. But do I need to be repeating the same properties for each new model? Do the models need to inherit from User data class? Is all of this specific to MVC pattern? How do the model class and the data class relate to each other in the actual implementation?

I'm using Blazor WebAssembly if that helps.


Solution

  • 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.