MSDN Learn - ASP.NET Core MVC

Deep Dive into MVC Architecture

Models in ASP.NET Core MVC

Understanding and effectively using models is fundamental to building robust and maintainable ASP.NET Core MVC applications.

In the Model-View-Controller (MVC) architectural pattern, the **Model** represents the application's data and the business logic that operates on that data. It's the core of your application's intelligence.

Purpose of Models

The primary purposes of models in an MVC application are:

Data Representation

Models are typically represented as plain old C# objects (POCOs) or classes that map directly to database tables (entities) or data transfer objects (DTOs).

For example, a simple `Product` model might look like this:

public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Description { get; set; } }

Business Logic

Business logic resides within the model. This logic dictates how data is processed, transformed, or validated. It's the "brains" of your application.

Consider a `Product` model with logic to determine if it's on sale:

public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public decimal DiscountPercentage { get; set; } public bool IsOnSale => DiscountPercentage > 0; public decimal SalePrice { get { if (IsOnSale) { return Price * (1 - DiscountPercentage / 100); } return Price; } } }

Validation

Models are also responsible for enforcing data integrity. This is achieved through validation. ASP.NET Core provides built-in data annotation attributes for common validation rules.

using System.ComponentModel.DataAnnotations; public class Product { public int Id { get; set; } [Required(ErrorMessage = "Product name is required.")] [StringLength(100, ErrorMessage = "Product name cannot exceed 100 characters.")] public string Name { get; set; } [Range(0.01, 10000.00, ErrorMessage = "Price must be between 0.01 and 10000.00.")] public decimal Price { get; set; } [StringLength(500)] public string Description { get; set; } }

These attributes can be used by model binders and the validation framework to automatically validate incoming data.

View Models vs. Domain Models

It's common to distinguish between Domain Models (representing core business entities) and View Models (tailored specifically for a particular view).

Using View Models helps to decouple your views from your core domain logic and ensures that only necessary data is passed to the client.

Creating Models

To create a model in ASP.NET Core MVC:

  1. Create a new C# class file.
  2. Define properties for the data you want to represent.
  3. Add any necessary business logic or validation attributes.
  4. (Optional) Create separate View Models for specific views.

Example: Product Model

Here's a more complete example of a `Product` model with validation attributes:

using System.ComponentModel.DataAnnotations; namespace MsdnLearn.Models { public class Product { public int ProductId { get; set; } [Required(ErrorMessage = "Please enter the product name.")] [Display(Name = "Product Name")] [StringLength(100)] public string Name { get; set; } [Required(ErrorMessage = "Please enter the price.")] [Display(Name = "Price")] [DataType(DataType.Currency)] [Range(0.01, 100000.00, ErrorMessage = "Price must be between 1 cent and 100,000 dollars.")] public decimal Price { get; set; } [StringLength(1000)] [Display(Name = "Description")] public string Description { get; set; } [Display(Name = "In Stock")] public bool IsAvailable { get; set; } = true; } }

Data Access Layer Interaction

Models themselves typically don't directly interact with the database. This responsibility is usually handled by a separate Data Access Layer (DAL), often implemented using Entity Framework Core or other ORMs. The Controller orchestrates the interaction, fetching data using the DAL and passing it to the Model, or saving Model data via the DAL.

For instance, a controller might:

  1. Receive a request to view product details.
  2. Use a repository or DbContext to fetch a `Product` object from the database.
  3. Pass this `Product` object to a View.