.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

目录
相关文章
|
存储 Cloud Native 数据处理
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
本文整理自阿里云资深技术专家、Apache Flink PMC 成员梅源在 Flink Forward Asia 新加坡 2025上的分享,深入解析 Flink 状态管理系统的发展历程,从核心设计到 Flink 2.0 存算分离架构,并展望未来基于流批一体的通用增量计算方向。
160 0
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
|
5天前
|
人工智能 中间件 API
AutoGen for .NET - 架构学习指南
《AutoGen for .NET 架构学习指南》系统解析微软多智能体框架,涵盖新旧双架构、核心设计、技术栈与实战路径,助你从入门到精通,构建分布式AI协同系统。
295 142
|
2月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
本文内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
300 15
|
2月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
|
13天前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
5天前
|
人工智能 API 数据库
Semantic Kernel .NET 架构学习指南
本指南系统解析微软Semantic Kernel .NET架构,涵盖核心组件、设计模式与源码结构,结合实战路径与调试技巧,助你从入门到贡献开源,掌握AI编排开发全栈技能。
55 2
|
5天前
|
Java Linux 虚拟化
【Docker】(1)Docker的概述与架构,手把手带你安装Docker,云原生路上不可缺少的一门技术!
1. Docker简介 1.1 Docker是什么 为什么docker会出现? 假定您在开发一款平台项目,您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。 您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。 您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。 **要求:**希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销 问题: 要如何确保应用能够在这些环境中运行和通过质量检测? 在部署过程中不出现令人头疼的版本、配置问题 无需重新编写代码和进行故障修复
71 1
|
5天前
|
人工智能 Kubernetes Cloud Native
Higress(云原生AI网关) 架构学习指南
Higress 架构学习指南 🚀写在前面: 嘿,欢迎你来到 Higress 的学习之旅!
87 0
|
6月前
|
运维 Cloud Native 测试技术
极氪汽车云原生架构落地实践
随着极氪数字业务的飞速发展,背后的 IT 技术也在不断更新迭代。极氪极为重视客户对服务的体验,并将系统稳定性、业务功能的迭代效率、问题的快速定位和解决视为构建核心竞争力的基石。

热门文章

最新文章