ASP.NET Core MVC的Model Binding会将HTTP Request数据,以映射的方式对应到参数中。基本上跟ASP.NET MVC差不多,但能Binding的来源更多了一些。
本篇将介绍ASP.NET Core的Model Binding。

Model Binding


要接收Client 传送来的数据,可以通过Action 的参数接收,如下:

  1. using Microsoft.AspNetCore.Mvc;
  2.  
  3. namespace MyWebsite.Controllers
  4. {
  5. public class HomeController : Controller
  6. {
  7. public IActionResult Index(int id)
  8. {
  9. return Content($"id: {id}");
  10. }
  11. }
  12. }

id就是从HTTP Request的内容被Binding的Model参数。
预设的Model Binding会从HTTP Request的三个地方取值(优先顺序由上到下):

  • Form

透过HTTP POST的form取值。如下图:

  • Route

是通过MVC Route URL取值。
如:http://localhost:5000/Home/Index/2,id取出的值就会是2。

  • Query

是通过URL Query参数取值。
如:http://localhost:5000/Home/Index?id=1,id取出的值就会是1。

如果三者都传入的话,会依照优先顺序取值Form > Route > Query

Binding Attributes


除了预设的三种Binding 来源外,还可以通过Model Binding Attributes 从HTTP Request 的其他数据中Binding。有以下6 种:

  • [FromHeader]

从HTTP Header取值。

  • [FromForm]

通过HTTP POST的form取值。

  • [FromRoute]

是通过MVC Route URL取值。

  • [FromQuery]

是通过URL Query参数取值。

  • [FromBody]

从HTTP Body取值,通常用于取JSON, XML。
ASP.NET Core MVC预设的序列化是使用JSON,如果要传XML格式做Model Binding的话,要在MVC服务加入XmlSerializerFormatters,如下:

Startup.cs

  1. // ...
  2. public void ConfigureServices(IServiceCollection services)
  3. {
  4. services.AddMvc()
  5. .AddXmlSerializerFormatters();
  6. }
  • [FromServices]

这个比较特别,不是从HTTP Request取值,而是从DI容器取值。
DI预设是使用Constructor Injection,但Controller可能会因为每个Action用到不一样的Service导致很多参数,所以也可以在Action注入Service。

范例程序


  1. // ...
  2. public class HomeController : Controller
  3. {
  4. public IActionResult FirstSample(
  5. [FromHeader]string header,
  6. [FromForm]string form,
  7. [FromRoute]string id,
  8. [FromQuery]string query)
  9. {
  10. return Content($"header: {header}, form: {form}, id: {id}, query: {query}");
  11. }
  12.  
  13. public IActionResult DISample([FromServices] ILogger<HomeController> logger)
  14. {
  15. return Content($"logger is null: {logger == null}.");
  16. }
  17.  
  18. public IActionResult BodySample([FromBody]UserModel model)
  19. {
  20. return Ok(model);
  21. }
  22. }
  23.  
  24. // ...
  25. public class UserModel
  26. {
  27. public int Id { get; set; }
  28. public string Name { get; set; }
  29. public string Email { get; set; }
  30. public string PhoneNumber { get; set; }
  31. public string Address { get; set; }
  32. }

输出结果

FirstSample输出结果:

DISample输出结果:
http://localhost:5000/Home/DISample

  1. logger is null: False.

BodySample输出结果:

  • JSON

  • XML

Model 验证


Model Binding 也可以顺便帮忙验证字段数据,只要在字段的属性上面带上Validation Attributes,如下:

  1. using System.ComponentModel.DataAnnotations;
  2. // ...
  3. public class UserModel
  4. {
  5. [Required]
  6. public int Id { get; set; }
  7.  
  8. [RegularExpression(@"\w+")]
  9. [StringLength(, MinimumLength = )]
  10. public string Name { get; set; }
  11.  
  12. [EmailAddress]
  13. public string Email { get; set; }
  14.  
  15. [Phone]
  16. public string PhoneNumber { get; set; }
  17.  
  18. [StringLength()]
  19. public string Address { get; set; }
  20. }

然后在Action 加上判断:

Controllers\HomeController.cs

  1. using Microsoft.AspNetCore.Mvc;
  2.  
  3. namespace MyWebsite.Controllers
  4. {
  5. public class HomeController : Controller
  6. {
  7. // ...
  8. public IActionResult BodySample([FromBody]UserModel model)
  9. {
  10. // 由于 Id 是 int 类型,int 默认为 0
  11. // 虽然带上了 [Required],但不是 null 所以算是有值。
  12. if (model.Id < )
  13. {
  14. ModelState.AddModelError("Id", "Id not exist");
  15. }
  16. if (ModelState.IsValid)
  17. {
  18. return Ok(model);
  19. }
  20. return BadRequest(ModelState);
  21. }
  22. }
  23. }

输入错误数据的输出结果:

.NET Core提供了很多的Validation Attributes,可以参考官网:

System.ComponentModel.DataAnnotations

自定义Validation Attributes


如果.NET Core提供的Validation Attributes不够用还可以自己做。
例如上述范例的数据模型多了生日字段,需要验证年龄:

  1. using System;
  2. using System.ComponentModel.DataAnnotations;
  3.  
  4. namespace MyWebsite.Attributes
  5. {
  6. public class AgeCheckAttribute : ValidationAttribute
  7. {
  8. public int MinimumAge { get; private set; }
  9. public int MaximumAge { get; private set; }
  10.  
  11. public AgeCheckAttribute(int minimumAge, int maximumAge)
  12. {
  13. MinimumAge = minimumAge;
  14. MaximumAge = maximumAge;
  15. }
  16.  
  17. protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  18. {
  19. var date = Convert.ToDateTime(value);
  20.  
  21. if (date.AddYears(MinimumAge) > DateTime.Today
  22. || date.AddYears(MaximumAge) < DateTime.Today)
  23. {
  24. return new ValidationResult(GetErrorMessage(validationContext));
  25. }
  26.  
  27. return ValidationResult.Success;
  28. }
  29.  
  30. private string GetErrorMessage(ValidationContext validationContext)
  31. {
  32. // 有帶 ErrorMessage 的话优先使用
  33. // [AgeCheck(18, 120, ErrorMessage="xxx")]
  34. if (!string.IsNullOrEmpty(this.ErrorMessage))
  35. {
  36. return this.ErrorMessage;
  37. }
  38.  
  39. // 自定义错误信息
  40. return $"{validationContext.DisplayName} can't be in future";
  41. }
  42. }
  43. }

参考


Overview of ASP.NET Core MVC
Introduction to model validation in ASP.NET Core MVC
ASP.NET CORE 2.0 MVC MODEL BINDING
ASP.NET CORE 2.0 MVC MODEL VALIDATION

原文链接

ASP.NET Core MVC 模型绑定 (转载)的更多相关文章

  1. ASP.NET Core MVC 模型绑定用法及原理

    前言 查询了一下关于 MVC 中的模型绑定,大部分都是关于如何使用的,以及模型绑定过程中的一些用法和概念,很少有关于模型绑定的内部机制实现的文章,本文就来讲解一下在 ASP.NET Core MVC ...

  2. .net core mvc 模型绑定 之 json and urlencoded

    .net core mvc 模型绑定, FromQuery,对应 url 中的 urlencoded string ("?key1=value1&key2=value2") ...

  3. ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览

    原文:Overview of ASP.NET Core MVC 作者:Steve Smith 翻译:张海龙(jiechen) 校对:高嵩 ASP.NET Core MVC 是使用模型-视图-控制器(M ...

  4. ASP.NET Core MVC 概述

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

  5. 你所不知道的ASP.NET Core MVC/WebApi基础系列(二)

    前言 好久没冒泡了,算起来估计有快半年没更新博客了,估计是我第一次停更如此之久,人总有懒惰的时候,时间越长越懒惰,但是呢,不学又不行,持续的惰性是不行dei,要不然会被时光所抛弃,技术所淘汰,好吧,进 ...

  6. 你所不知道的ASP.NET Core MVC/WebApi基础系列 (二)

    转自博客:https://www.cnblogs.com/CreateMyself/p/10604293.html 前言 本节内容,我们来讲讲.NET Core当中的模型绑定系统.模型绑定原理.自定义 ...

  7. ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门

    一.前言 1.本文主要内容 ASP.NET Core MVC路由工作原理概述 ASP.NET Core MVC带路径参数的路由示例 ASP.NET Core MVC固定前/后缀的路由示例 ASP.NE ...

  8. ASP.NET Core 入门笔记4,ASP.NET Core MVC路由入门

    敲了一部分,懒得全部敲完,直接复制大佬的博客了,如有侵权,请通知我尽快删除修改 摘抄自https://www.cnblogs.com/ken-io/p/aspnet-core-tutorial-mvc ...

  9. ASP.NET Core MVC/WebAPi 模型绑定探索 转载https://www.cnblogs.com/CreateMyself/p/6246977.html

    前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用 ...

随机推荐

  1. AngularJS学习之 angular-file-upload控件使用方法

    1.官方链接 https://github.com/nervgh/angular-file-upload 2.安装到项目中 bower install angular-file-upload(安装完成 ...

  2. SwipeRefreshLayout嵌套ScrollView实现下拉刷新

    API doc:http://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html 首先须 ...

  3. nginx 配置 非80 的其他 端口

    如果nginx的监听端口不是默认的80端口,改为其他非80端口后,后端服务tomcat中的request.getServerPort()方法无法获得正确的端口号,仍然返回到80端口.在response ...

  4. ElementUI制作树形表组件

    提要 最近项目中需要用到树形表格来描述部门.区域之间的父子展开关系.但是已经在项目中使用的Vue的成熟组件ElementUI以及iViewUI组件都没有提供相应的树形表格组件,无奈找了其他替代方案也都 ...

  5. qt调用js,js调用qt

    <html> <script language="JavaScript"> function qtcalljs() { alert("sdfsd& ...

  6. Prometheus Node_exporter 详解

    Basic CPU / Mem / Disk Info https://www.cnblogs.com/qianyuliang/p/10479515.html Basic CPU / Mem / Di ...

  7. Linux 中 FQDN 查询及设置

    FQDN:(Fully Qualified Domain Name)全限定域名:同时带有主机名和域名的名称 其实就是标注一个主机的完整域名.比如我的域名为 ifrom.top 那么它的邮件服务器的主机 ...

  8. man -k : nothing appropriate.

    ➜ workplace man -k zip zip: nothing appropriate. 出现这种情况,是索引库没有建立. man 和 whatis 共用一个索引库的. 我们使用  man w ...

  9. 【8】python文件的读写方法

    (1).读文件的步骤: (1)打开文件 open(path,flag,encoding,[errors]) path:打开路径 flag:打开方式 r(只读) rb(二进制格式) r+(可以读写) w ...

  10. 题解 P1120 【小木棍 [数据加强版]】

    题面 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮 ...