.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 存算分离架构,并展望未来基于流批一体的通用增量计算方向。
245 0
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
|
3月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
本文内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
387 16
|
3月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
|
1月前
|
人工智能 Kubernetes Cloud Native
Higress(云原生AI网关) 架构学习指南
Higress 架构学习指南 🚀写在前面: 嘿,欢迎你来到 Higress 的学习之旅!
369 0
|
7月前
|
运维 Cloud Native 测试技术
极氪汽车云原生架构落地实践
随着极氪数字业务的飞速发展,背后的 IT 技术也在不断更新迭代。极氪极为重视客户对服务的体验,并将系统稳定性、业务功能的迭代效率、问题的快速定位和解决视为构建核心竞争力的基石。
|
4月前
|
运维 监控 Cloud Native
从“守机器”到“写策略”——云原生架构把运维逼成了架构师
从“守机器”到“写策略”——云原生架构把运维逼成了架构师
91 1
|
11月前
|
运维 Cloud Native 持续交付
深入理解云原生架构及其在现代企业中的应用
随着数字化转型的浪潮席卷全球,企业正面临着前所未有的挑战与机遇。云计算技术的迅猛发展,特别是云原生架构的兴起,正在重塑企业的IT基础设施和软件开发模式。本文将深入探讨云原生的核心概念、关键技术以及如何在企业中实施云原生策略,以实现更高效的资源利用和更快的市场响应速度。通过分析云原生架构的优势和面临的挑战,我们将揭示它如何助力企业在激烈的市场竞争中保持领先地位。
284 13
|
11月前
|
Kubernetes Cloud Native 微服务
探索云原生技术:容器化与微服务架构的融合之旅
本文将带领读者深入了解云原生技术的核心概念,特别是容器化和微服务架构如何相辅相成,共同构建现代软件系统。我们将通过实际代码示例,探讨如何在云平台上部署和管理微服务,以及如何使用容器编排工具来自动化这一过程。文章旨在为开发者和技术决策者提供实用的指导,帮助他们在云原生时代中更好地设计、部署和维护应用。
|
6月前
|
人工智能 Cloud Native 容灾
深圳农商银行三代核心系统全面投产 以云原生架构筑牢数字化转型基石
深圳农商银行完成第三代核心系统全面上云,日均交易超3000万笔,峰值处理效率提升2倍以上。扎根深圳70余年,与阿里云共建“两地三中心”分布式云平台,实现高可用体系及全栈护航。此次云原生转型为行业提供可复制样本,未来将深化云计算与AI合作,推动普惠金融服务升级。
477 17
|
6月前
|
存储 Cloud Native 关系型数据库
PolarDB开源:云原生数据库的架构革命
本文围绕开源核心价值、社区运营实践和技术演进路线展开。首先解读存算分离架构的三大突破,包括基于RDMA的分布式存储、计算节点扩展及存储池扩容机制,并强调与MySQL的高兼容性。其次分享阿里巴巴开源治理模式,涵盖技术决策、版本发布和贡献者成长体系,同时展示企业应用案例。最后展望技术路线图,如3.0版本的多写多读架构、智能调优引擎等特性,以及开发者生态建设举措,推荐使用PolarDB-Operator实现高效部署。
343 3

热门文章

最新文章