.net core mvc学习心得总结

在我个人的编程学习道路上,.NET MVC框架的学习无疑是一个重要的里程碑。这个强大的框架不仅提供了一种全新的开发模式,也让我对Web开发有了更深入的理解。以下是我在学习.NET MVC过程中的一些心得体会。

基本概念

.NET Core MVC是一种基于模型-视图-控制器(MVC)架构的Web应用程序框架。它遵循了典型的MVC设计模式,将应用程序的逻辑、数据和表示分离,使得代码更易于维护和扩展。以下是.NET Core MVC的基本概念和架构:

  1. 中间件(Middleware):中间件是处理HTTP请求和响应的组件。它可以执行诸如身份验证、授权、日志记录等任务。在.NET Core MVC中,中间件是一个函数,接收HttpContext对象和一个委托,返回Task。中间件按顺序执行,可以调用下一个中间件或直接返回响应。

  2. 控制器(Controller):控制器是处理用户请求并生成响应的组件。它负责从模型中获取数据,将其传递给视图进行呈现。在.NET Core MVC中,控制器是一个类,继承自Microsoft.AspNetCore.Mvc.Controller基类。控制器中的操作方法(Action Method)对应于HTTP动词(如GET、POST等),返回ActionResult对象。

  3. 视图(View):视图是用于呈现模型数据的模板。它通常使用HTML、CSS和JavaScript编写,但也可以是其他格式,如PDF或Excel。在.NET Core MVC中,视图是一个文件,扩展名为.cshtml(Razor语法)或.vbhtml(VB.NET语法)。视图可以使用布局(Layout)来共享公共部分,如导航栏和页脚。

  4. 路由(Routing):路由是将URL映射到控制器操作的方法。在.NET Core MVC中,路由配置在Startup.cs文件中的Configure方法中完成。路由使用端点(Endpoint)表示,包括HTTP动词、路径和参数。例如,一个路由可能是“/products/{id}”,其中“products”是路径,“{id}”是参数。当用户访问这个URL时,.NET Core MVC会根据路由找到对应的控制器操作并执行。

总之,.NET Core MVC的基本概念和架构包括中间件、控制器、视图和路由。这些组件共同工作,使得开发者可以轻松地构建可扩展、可维护的Web应用程序。

依赖注入

依赖注入(Dependency Injection,简称DI)是一种设计模式,用于降低代码之间的耦合度。通过将对象的依赖关系从对象内部转移到外部,我们可以更容易地测试和重用代码。在.NET Core MVC中,我们可以使用内置的依赖注入容器来管理服务和组件。

以下是如何在.NET Core MVC中使用依赖注入的示例:

1. 首先,创建一个接口和实现类。例如,我们创建一个IProductService接口和一个ProductService类:

public interface IProductService
{
    List<Product> GetAllProducts();
}

public class ProductService : IProductService
{
    private readonly List<Product> _products;

    public ProductService()
    {
        _products = new List<Product>
        {
            new Product { Id = 1, Name = "Product 1" },
            new Product { Id = 2, Name = "Product 2" },
            new Product { Id = 3, Name = "Product 3" },
        };
    }

    public List<Product> GetAllProducts() => _products;
}

2. 然后,在Startup.cs文件中的ConfigureServices方法中注册IProductService接口和ProductService类:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddSingleton<IProductService, ProductService>();
}

这里,我们使用AddSingleton方法将ProductService类注册为IProductService接口的实现。这意味着在整个应用程序中,只有一个ProductService实例被创建和使用。

3. 接下来,在控制器中使用依赖注入。首先,将IProductService接口添加到控制器的构造函数参数中:

public class ProductsController : Controller
{
    private readonly IProductService _productService;

    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }
}

4. 现在,我们可以在控制器的操作方法中使用IProductService接口来获取产品数据:

public async Task<IActionResult> Index()
{
    var products = await _productService.GetAllProducts();
    return View(products);
}

通过这种方式,我们可以轻松地管理和测试服务和组件。此外,由于DI容器负责创建和管理对象,我们还可以避免在代码中直接使用new关键字创建对象,从而降低耦合度。

属性路由来定义自定义的URL路径

遵循单一职责原则(Single Responsibility Principle,简称SRP)是编写高质量代码的关键。在.NET Core MVC中,我们应该确保控制器中的逻辑保持简洁,并专注于处理特定类型的请求。以下是一些建议,以帮助实现这一目标:

1. 将业务逻辑移到服务层:控制器的主要职责是处理HTTP请求和响应,而不是执行业务逻辑。因此,我们应该将业务逻辑移到单独的服务层,并在控制器中使用这些服务。例如,我们可以创建一个IProductService接口和一个ProductService类来处理与产品相关的业务逻辑。


public interface IProductService
{
    List<Product> GetAllProducts();
}

public class ProductService : IProductService
{
    private readonly List<Product> _products;

    public ProductService()
    {
        _products = new List<Product>
        {
            new Product { Id = 1, Name = "Product 1" },
            new Product { Id = 2, Name = "Product 2" },
            new Product { Id = 3, Name = "Product 3" },
        };
    }

    public List<Product> GetAllProducts() => _products;
}
```

然后,在控制器中使用依赖注入来调用服务层的方法:


public class ProductsController : Controller
{
    private readonly IProductService _productService;

    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }

    public async Task<IActionResult> Index()
    {
        var products = await _productService.GetAllProducts();
        return View(products);
    }
}
```

2. 使用视图模型(ViewModel):视图模型是一种用于封装视图所需的数据和逻辑的类。通过使用视图模型,我们可以将控制器中的数据传递给视图,同时保持控制器的逻辑简洁。例如,我们可以创建一个ProductIndexViewModel类来封装产品列表和分页信息:


public class ProductIndexViewModel
{
    public List<Product> Products { get; set; } = new List<Product>();
    public int PageNumber { get; set; } = 1;
    public int PageSize { get; set; } = 10;
}
```

然后,在控制器的操作方法中,使用视图模型将数据传递给视图:

```csharp
public async Task<IActionResult> Index(int pageNumber = 1, int pageSize = 10)
{
    var products = await _productService.GetAllProducts();
    var viewModel = new ProductIndexViewModel { Products = products, PageNumber = pageNumber, PageSize = pageSize };
    return View(viewModel);
}
```

3. 避免在控制器中执行耗时操作:控制器应该专注于处理HTTP请求和响应,而不是执行耗时的操作,如数据库查询或复杂的业务逻辑。这些操作应该在服务层中执行,并将结果返回给控制器。这样,我们可以确保控制器的逻辑保持简洁,并提高应用程序的性能。

单一职责原则(SRP)

遵循单一职责原则(Single Responsibility Principle,简称SRP)是编写高质量代码的关键。在.NET Core MVC中,我们应该确保控制器中的逻辑保持简洁,并专注于处理特定类型的请求。以下是一些建议,以帮助实现这一目标:

1. 将业务逻辑移到服务层:控制器的主要职责是处理HTTP请求和响应,而不是执行业务逻辑。因此,我们应该将业务逻辑移到单独的服务层,并在控制器中使用这些服务。例如,我们可以创建一个IProductService接口和一个ProductService类来处理与产品相关的业务逻辑。

```csharp
public interface IProductService
{
    List<Product> GetAllProducts();
}

public class ProductService : IProductService
{
    private readonly List<Product> _products;

    public ProductService()
    {
        _products = new List<Product>
        {
            new Product { Id = 1, Name = "Product 1" },
            new Product { Id = 2, Name = "Product 2" },
            new Product { Id = 3, Name = "Product 3" },
        };
    }

    public List<Product> GetAllProducts() => _products;
}
```

然后,在控制器中使用依赖注入来调用服务层的方法:

```csharp
public class ProductsController : Controller
{
    private readonly IProductService _productService;

    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }

    public async Task<IActionResult> Index()
    {
        var products = await _productService.GetAllProducts();
        return View(products);
    }
}
```

2. 使用视图模型(ViewModel):视图模型是一种用于封装视图所需的数据和逻辑的类。通过使用视图模型,我们可以将控制器中的数据传递给视图,同时保持控制器的逻辑简洁。例如,我们可以创建一个ProductIndexViewModel类来封装产品列表和分页信息:

```csharp
public class ProductIndexViewModel
{
    public List<Product> Products { get; set; } = new List<Product>();
    public int PageNumber { get; set; } = 1;
    public int PageSize { get; set; } = 10;
}
```

然后,在控制器的操作方法中,使用视图模型将数据传递给视图:

```csharp
public async Task<IActionResult> Index(int pageNumber = 1, int pageSize = 10)
{
    var products = await _productService.GetAllProducts();
    var viewModel = new ProductIndexViewModel { Products = products, PageNumber = pageNumber, PageSize = pageSize };
    return View(viewModel);
}
```

3. 避免在控制器中执行耗时操作:控制器应该专注于处理HTTP请求和响应,而不是执行耗时的操作,如数据库查询或复杂的业务逻辑。这些操作应该在服务层中执行,并将结果返回给控制器。这样,我们可以确保控制器的逻辑保持简洁,并提高应用程序的性能。

视图模型(View Models)来传递数据

在.NET Core MVC中,我们建议使用视图模型(View Models)而不是直接使用实体模型来传递数据给视图。视图模型是专门用于表示视图所需的数据的类,它可以帮助我们更好地组织和管理数据,提高代码的可读性和可维护性。以下是如何在.NET Core MVC中使用视图模型的示例:

1. 首先,创建一个视图模型类,该类包含视图所需的属性和数据。例如,我们可以创建一个ProductIndexViewModel类来封装产品列表和分页信息:

```csharp
public class ProductIndexViewModel
{
    public List<Product> Products { get; set; } = new List<Product>();
    public int PageNumber { get; set; } = 1;
    public int PageSize { get; set; } = 10;
}
```

2. 然后,在控制器的操作方法中,创建一个视图模型实例,并将数据填充到该实例中。例如,在ProductsController中的Index操作方法中:

```csharp
public async Task<IActionResult> Index(int pageNumber = 1, int pageSize = 10)
{
    var products = await _productService.GetAllProducts();
    var viewModel = new ProductIndexViewModel { Products = products, PageNumber = pageNumber, PageSize = pageSize };
    return View(viewModel);
}
```

3. 接下来,更新视图文件(如Index.cshtml),以便使用视图模型中的属性。例如:

```html
@model ProductIndexViewModel
<!-- ... -->
<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Price</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var product in Model.Products)
        {
            <tr>
                <td>@product.Name</td>
                <td>@product.Price</td>
            </tr>
        }
    </tbody>
</table>
<!-- ... -->
```

4. 最后,确保在Startup.cs文件中的ConfigureServices方法中注册视图引擎,以便正确地解析视图文件:

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages(); // 如果使用Razor页面,请添加此行。
}
```

通过这种方式,我们可以使用视图模型来传递数据给视图,使代码更加清晰、易于维护,并提高应用程序的可测试性。

数据库迁移(Database Migrations)

在.NET Core MVC中,我们可以使用Entity Framework Core的数据库迁移功能来管理数据库架构变更。数据库迁移允许我们定义和应用对数据库模式(包括表、列、索引等)的更改,而无需直接修改数据库脚本。以下是如何使用数据库迁移的示例:

1. 首先,确保已安装Entity Framework Core的相关包。在项目中的包管理器控制台中运行以下命令:

```
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Tools
```

2. 创建一个继承自DbContext的类,该类将表示与数据库的交互。例如,我们可以创建一个名为ApplicationDbContext的类:

```csharp
public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public DbSet<Product> Products { get; set; }
}
```

3. 在Startup.cs文件中的ConfigureServices方法中注册ApplicationDbContext和数据库迁移服务:

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
}
```

4. 运行以下命令,以根据模型创建数据库架构:

```
dotnet ef migrations add InitialCreate --context ApplicationDbContext
```

这将创建一个名为“InitialCreate”的迁移文件,其中包含对数据库架构的更改。

5. 更新项目的Program.cs文件中的Main方法,以便在运行应用程序时应用迁移:

```csharp
public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();
    using (var scope = host.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        try
        {
            var context = services.GetRequiredService<ApplicationDbContext>();
            context.Database.Migrate(); // 应用迁移
            host.Run(); // 启动应用程序
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while applying migrations.");
        }
    }
}
```

6. 现在,当我们对模型进行更改时,可以再次运行以下命令来生成新的迁移文件:

```
dotnet ef migrations add NewMigration --context ApplicationDbContext
```

7. 最后,运行以下命令以将更改应用于数据库:

```
dotnet ef database update --context ApplicationDbContext
```

通过这种方式,我们可以使用数据库迁移来管理数据库架构变更,使代码更加清晰、易于维护,并提高应用程序的可测试性。

EF Core的Code First方法

思路:
1. 创建一个实体类,例如Student。
2. 使用Entity Framework Core的Code First方法来定义和配置实体模型。
3. 在DbContext类中配置数据库连接字符串。
4. 使用DbContext实例来执行数据库操作。

代码:

```csharp
// 1. 创建一个实体类,例如Student。
public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

// 2. 使用Entity Framework Core的Code First方法来定义和配置实体模型。
// 在项目中创建一个新的文件夹,例如Models,然后在该文件夹中创建一个名为Student.cs的文件。将以下代码粘贴到Student.cs文件中。

using System.ComponentModel.DataAnnotations;

namespace YourNamespace
{
    public class Student
    {
        [Key]
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }

        [Range(1, 100)]
        public int Age { get; set; }
    }
}

// 3. 在DbContext类中配置数据库连接字符串。
// 在项目中创建一个新的文件夹,例如Data,然后在该文件夹中创建一个名为AppDbContext.cs的文件。将以下代码粘贴到AppDbContext.cs文件中。

using Microsoft.EntityFrameworkCore;

namespace YourNamespace.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options)
            : base(options)
        {
        }

        public DbSet<Student> Students { get; set; }
    }
}

// 4. 使用DbContext实例来执行数据库操作。
// 在Program.cs文件中,添加以下代码以配置数据库连接字符串并创建DbContext实例。

using System;
using Microsoft.EntityFrameworkCore;

namespace YourConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var options = new DbContextOptionsBuilder<AppDbContext>()
                .UseSqlServer("your_connection_string")
                .Options;

            using (var context = new AppDbContext(options))
            {
                // 添加学生
                var student = new Student { Name = "张三", Age = 20 };
                context.Students.Add(student);
                context.SaveChanges();

                // 查询学生
                var students = context.Students.ToList();
                foreach (var student in students)
                {
                    Console.WriteLine($"Id: {student.Id}, Name: {student.Name}, Age: {student.Age}");
                }
            }
        }
    }
}
```

DTO(Data Transfer Objects)

DTO(Data Transfer Objects)是一种设计模式,用于减少数据传输的量,提高性能。它主要用于在不同层之间传输数据,例如在Web应用程序中,前端和后端之间的数据传输。

思路:
1. 创建一个DTO类,包含需要传输的数据属性。
2. 在前端和后端之间传递数据时,使用DTO类作为数据传输对象。
3. 在后端处理数据时,只处理DTO类中的属性,而不是整个对象。

代码示例:

```python
# DTO类
class UserDTO:
    def __init__(self, id, name, age):
        self.id = id
        self.name = name
        self.age = age

# 前端传递数据
user_data = {
    "id": 1,
    "name": "张三",
    "age": 25
}
user_dto = UserDTO(**user_data)

# 后端处理数据
def get_user_by_id(user_id):
    # 假设这里是从数据库中获取用户数据的代码
    user_data = {
        "id": user_id,
        "name": "张三",
        "age": 25
    }
    return user_data

# 使用DTO类进行数据传输
user_dto = get_user_by_id(user_dto.id)
print(user_dto.name, user_dto.age)
```

总结

最后,我想对所有正在学习.NET MVC的人说:学习是一个持续的过程,只有通过不断的学习和实践,我们才能真正掌握一个框架。不要害怕困难,不要放弃希望,只要你坚持下去,你一定能够成功。

在学习.NET MVC的过程中,我收获了很多。我不仅掌握了一种新的开发模式,也提高了我的编程技能。我相信,通过学习.NET MVC,我将能够在未来的编程生涯中取得更大的进步。

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值