.NET 云原生架构师训练营(模块二 基础巩固 MVC终结点)--学习笔记

简介: - MVC与MVVM- 模型绑定- 自定义模型绑定器- 模型验证- 返回数据处理

2.3.4 Web API -- MVC终结点

  • MVC与MVVM
  • 模型绑定
  • 自定义模型绑定器
  • 模型验证
  • 返回数据处理

MVC与MVVM

MVC

ASP.NET Core MVC 概述:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/overview?view=aspnetcore-5.0

20.jpg

MVVM

ASP.NET Core 中的 Razor Pages 介绍:https://docs.microsoft.com/zh-cn/aspnet/core/razor-pages/?view=aspnetcore-5.0&tabs=visual-studio

Razor Pages 没有 Controller,Model 中可以包含方法

21.jpg

ASP.NET Core MVC 注入

services.AddControllers();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

MVC Endpoint

22.jpg

模型绑定

  • 什么是模型绑定
  • 来源有哪些
  • 复杂的数据绑定

ASP.NET Core 中的模型绑定:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/model-binding?view=aspnetcore-5.0

什么是模型绑定

控制器和 Razor 页面处理来自 HTTP 请求的数据。 例如,路由数据可以提供一个记录键,而发布的表单域可以为模型的属性提供一个值。 编写代码以检索这些值,并将其从字符串转换为 .NET 类型不仅繁琐,而且还容易出错。

模型绑定会自动化该过程。 模型绑定系统:

  • 从各种源(如路由数据、表单域和查询字符串)中检索数据。
  • Razor在方法参数和公共属性中向控制器和页面提供数据。
  • 将字符串数据转换为 .NET 类型。
  • 更新复杂类型的属性。

来源有哪些

  • [FromQuery] -从查询字符串获取值。
  • [FromRoute] -从路由数据中获取值。
  • [FromForm] -从已发布的表单字段中获取值。
  • [FromBody] -从请求正文中获取值。
  • [FromHeader] -从 HTTP 标头中获取值。

从路由数据中获取值

[HttpGet]
[Route("option/{id}")]
public IActionResult GetOption([FromRoute] int id)
{
    return Ok(new {id});
}

从查询字符串获取值

[HttpGet]
[Route("option/{id}")]
public IActionResult GetOption([FromRoute] int id, [FromQuery] string name)
{
    return Ok(new {id, name});
}

从 HTTP 标头中获取值

[HttpGet]
[Route("option/{id}")]
public IActionResult GetOption([FromRoute] int id, [FromQuery] string name,[FromHeader] string termId)
{
    return Ok(new {id, name, termId});
}

从已发布的表单字段中获取值

[HttpPost]
[Route("option/from")]
public IActionResult CreateOption([FromForm] string name, [FromForm] string id)
{
    return Ok(new {name, id});
}

从请求正文中获取值

[HttpPost]
[Route("option/body")]
public IActionResult CreateOption([FromBody] string name)
{
    return Ok(name);
}

复杂的数据绑定

  • 对象
  • 集合
  • 字典

对象

public class Student
{
    public int Id { get; set; }

    public string Name { get; set; }
}

[HttpPost]
[Route("option/body")]
public IActionResult CreateOption([FromBody] Student student)
{
    return Ok(student);
}

字典

[HttpGet]
[Route("option")]
public IActionResult GetOption([FromQuery] Dictionary<int, string> dic)
{
    var students = new List<Student>();

    foreach (var item in dic)
    {
        students.Add(new Student {Id = item.Key, Name = item.Value});
    }

    return Ok(students);
}

启动程序,访问:https://localhost:5001/config/option?dic[1001]=ming$dic[1002]=rank&dic[1003]=abc

输出:

[{"id":1001,"name":"ming$dic[1002]=rank"},{"id":1003,"name":"abc"}]

自定义模型绑定器

ASP.NET Core 中的自定义模型绑定:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-5.0

ModelBinder

[ModelBinder(BinderType = typeof(AuthorEntityBinder))]
public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string GitHub { get; set; }
    public string Twitter { get; set; }
    public string BlogUrl { get; set; }
}

public class AuthorEntityBinder : IModelBinder

ModelBinderProvider

public class AuthorEntityBinderProvider : IModelBinderProvider

services.AddControllers(options =>
{
    options.ModelBinderProviders.Insert(0, new AuthorEntityBinderProvider());
});

模型验证

  • 什么是模型验证
  • 模型验证的特性与消息
  • FluentValidation

什么是模型验证

ASP.NET Core MVC 和页面中的模型验证 Razor:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/validation?view=aspnetcore-5.0

Web 应用负责检查 ModelState.IsValid 并做出相应响应

if (!ModelState.IsValid)
{
    return Page();
}

模型验证的特性与消息

  • [CreditCard]:验证属性是否具有信用卡格式。
  • [Compare]:验证模型中的两个属性是否匹配。
  • [EmailAddress]:验证属性是否具有电子邮件格式。
  • [Phone]:验证属性是否具有电话号码格式。
  • [Range]:验证属性值是否在指定的范围内。
  • [RegularExpression]:验证属性值是否与指定的正则表达式匹配。
  • [Required]:验证字段是否不为 null。
  • [StringLength]:验证字符串属性值是否不超过指定长度限制。
  • [Url]:验证属性是否具有 URL 格式。
  • [Remote]:通过在服务器上调用操作方法来验证客户端上的输入。

[Required] [Range]

public class Student
{
    [Required]
    [Range(1,10,ErrorMessage = "id 为 1-10 之间的数字")]
    public int Id { get; set; }

    public string Name { get; set; }
}

ModelState

[HttpPost]
[Route("option/body")]
public IActionResult CreateOption([FromBody] Student student)
{
    if (!ModelState.IsValid)
    {
        return ValidationProblem();
    }

    return Ok(student);
}

FluentValidation

不同场景下同一个模型有不同的验证规则,最好将模型与验证分开

表达式写法:

public class CustomerValidator : AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(x => x.Surname).NotEmpty();
    RuleFor(x => x.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(x => x.Discount).NotEqual(0).When(x => x.HasDiscount);
    RuleFor(x => x.Address).Length(20, 250);
    RuleFor(x => x.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

Installation:https://docs.fluentvalidation.net/en/latest/installation.html

Install-Package FluentValidation

StudentValidator

namespace HelloApi.Validations
{
    public class StudentValidator : AbstractValidator<Student>
    {
        public StudentValidator()
        {
            RuleFor(s => s.Id).InclusiveBetween(1,10).WithMessage("id需要在1和10之间");
        }
    }
}

ASP.NET Core Getting Started:https://docs.fluentvalidation.net/en/latest/aspnet.html

dotnet add package FluentValidation.AspNetCore

ConfigureServices

单个添加

services.AddControllers()
    .AddFluentValidation();

// 通过依赖注入的方式(单个添加)
services.AddTransient<IValidator<Student>, StudentValidator>();

全部添加

// 通过扫描程序集的方式(全部添加)
services.AddControllers()
    .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<StudentValidator>());

返回数据处理

  • 返回数据类型
  • 格式化响应数据

返回数据类型

ASP.NET Core Web API 中控制器操作的返回类型:https://docs.microsoft.com/zh-cn/aspnet/core/web-api/action-return-types?view=aspnetcore-5.0

  • 特定类型
  • IActionResult
  • ActionResult

特定类型:最简单的操作返回基元或复杂数据类型(如 string 或自定义对象类型)

IActionResult:常见返回类型为 BadRequestResult (400)、NotFoundResult (404) 和 OkObjectResult (200)

[HttpPost]
[Route("option/body")]
public IActionResult CreateOption([FromBody] Student student)
{
    if (!ModelState.IsValid)
    {
        return ValidationProblem();
    }

    //return BadRequest();

    //return NotFound();

    return Ok(student);
}

格式化响应数据

设置 ASP.NET Core Web API 中响应数据的格式:https://docs.microsoft.com/zh-cn/aspnet/core/web-api/advanced/formatting?view=aspnetcore-5.0

浏览器和内容协商

services.AddControllers(options =>
{
    options.RespectBrowserAcceptHeader = true;// 浏览器和内容协商
});

添加 XML 格式支持

services.AddControllers(options =>
{
    options.RespectBrowserAcceptHeader = true; // 浏览器和内容协商
})
.AddXmlSerializerFormatters() // 添加 XML 格式支持
.AddFluentValidation();

启动程序,添加 XML Headers 访问:

23.jpg

添加基于 Newtonsoft.Json 的 JSON 格式支持

添加 nuget 包:Microsoft.AspNetCore.Mvc.NewtonsoftJson

services.AddControllers(options =>
{
    options.RespectBrowserAcceptHeader = true; // 浏览器和内容协商
})
.AddNewtonsoftJson()// 添加基于 Newtonsoft.Json 的 JSON 格式支持
.AddXmlSerializerFormatters() // 添加 XML 格式支持
.AddFluentValidation();

GitHub源码链接:

https://github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/HelloApi

目录
相关文章
|
6月前
|
设计模式 存储 前端开发
MVVM、MVC、MVP三种常见软件架构设计模式的区别
MVC、MVP 和 MVVM 是三种常见的软件架构设计模式,主要通过分离关注点的方式来组织代码结构,优化开发效率。
128 12
|
16天前
|
Kubernetes Cloud Native Ubuntu
庆祝 .NET 9 正式版发布与 Dapr 从 CNCF 毕业:构建高效云原生应用的最佳实践
2024年11月13日,.NET 9 正式版发布,Dapr 从 CNCF 毕业,标志着云原生技术的成熟。本文介绍如何使用 .NET 9 Aspire、Dapr 1.14.4、Kubernetes 1.31.0/Containerd 1.7.14、Ubuntu Server 24.04 LTS 和 Podman 5.3.0-rc3 构建高效、可靠的云原生应用。涵盖环境准备、应用开发、Dapr 集成、容器化和 Kubernetes 部署等内容。
42 5
|
22天前
|
存储 前端开发 数据可视化
在实际项目中,如何选择使用 Flux 架构或传统的 MVC 架构
在实际项目中选择使用Flux架构或传统MVC架构时,需考虑项目复杂度、团队熟悉度和性能需求。Flux适合大型、高并发应用,MVC则适用于中小型、逻辑简单的项目。
|
2月前
|
Cloud Native API C#
.NET云原生应用实践(一):从搭建项目框架结构开始
.NET云原生应用实践(一):从搭建项目框架结构开始
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
43 7
|
3月前
|
编解码 Linux 开发工具
Linux平台x86_64|aarch64架构RTMP推送|轻量级RTSP服务模块集成说明
支持x64_64架构、aarch64架构(需要glibc-2.21及以上版本的Linux系统, 需要libX11.so.6, 需要GLib–2.0, 需安装 libstdc++.so.6.0.21、GLIBCXX_3.4.21、 CXXABI_1.3.9)。
|
4月前
|
设计模式 存储 前端开发
MVC革命:如何用一个设计模式重塑你的应用架构,让代码重构变得戏剧性地简单!
【8月更文挑战第22天】自定义MVC(Model-View-Controller)设计模式将应用分为模型、视图和控制器三个核心组件,实现关注点分离,提升代码可维护性和扩展性。模型管理数据和业务逻辑,视图负责数据显示与用户交互,控制器处理用户输入并协调模型与视图。通过示例代码展示了基本的MVC框架实现,可根据需求扩展定制。MVC模式灵活性强,支持单元测试与多人协作,但需注意避免控制器过度复杂化。
44 1
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
63 0
|
4月前
|
开发者 前端开发 Java
架构模式的诗与远方:如何在MVC的田野上,用Struts 2编织Web开发的新篇章
【8月更文挑战第31天】架构模式是软件开发的核心概念,MVC(Model-View-Controller)通过清晰的分层和职责分离,成为广泛采用的模式。随着业务需求的复杂化,Struts 2框架应运而生,继承MVC优点并引入更多功能。本文探讨从MVC到Struts 2的演进,强调架构模式的重要性。MVC将应用程序分为模型、视图和控制器三部分,提高模块化和可维护性。
48 0
|
4月前
|
存储 前端开发 数据库
神秘编程世界惊现强大架构!Web2py 的 MVC 究竟隐藏着怎样的神奇魔力?带你探索实际应用之谜!
【8月更文挑战第31天】在现代 Web 开发中,MVC(Model-View-Controller)架构被广泛应用,将应用程序分为模型、视图和控制器三个部分,有助于提高代码的可维护性、可扩展性和可测试性。Web2py 是一个采用 MVC 架构的 Python Web 框架,其中模型处理数据和业务逻辑,视图负责呈现数据给用户,控制器则协调模型和视图之间的交互。
40 0
下一篇
无影云桌面