asp.net core 参数接收及模型绑定
ASP.NET Core MVC的Model Binding会将HTTP Request数据,以映射的方式对应到参数中。基本上跟ASP.NET MVC差不多,但能Binding的来源更多了一些。
本篇将介绍ASP.NET Core的Model Binding。
参数
HttpRequest
HttpRequest 是用户请求对象
QueryString
Form
Cookie
Session
Header
实例:
        public IActionResult Index()
        {
            QueryString x = Request.QueryString; //	?a=1
            string x = Request.Query["a"]; //1
            return View();
        }
HttpContext
HttpContext 是用户请求上下文
提供Session属性获取Session对象Session.Set设置Session.Remove移除Session.TryGetValue获取数据
Model Binding
要接收Client 传送来的数据,可以通过Action 的参数接收,如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 | usingMicrosoft.AspNetCore.Mvc;namespaceMyWebsite.Controllers{    publicclassHomeController : Controller    {        publicIActionResult Index(intid)        {            returnContent($"id: {id}");        }    }} | 
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 3 4 5 6 | // ...publicvoidConfigureServices(IServiceCollection services){    services.AddMvc()            .AddXmlSerializerFormatters();} | 
- 
[FromServices] 
 这个比较特别,不是从HTTP Request取值,而是从DI容器取值。
 DI预设是使用Constructor Injection,但Controller可能会因为每个Action用到不一样的Service导致很多参数,所以也可以在Action注入Service。
范例程序
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // ...publicclassHomeController : Controller{    publicIActionResult FirstSample(        [FromHeader]stringheader,        [FromForm]stringform,        [FromRoute]stringid,        [FromQuery]stringquery)    {        returnContent($"header: {header}, form: {form}, id: {id}, query: {query}");    }        publicIActionResult DISample([FromServices] ILogger<HomeController> logger)    {        returnContent($"logger is null: {logger == null}.");    }    publicIActionResult BodySample([FromBody]UserModel model)    {        returnOk(model);    }}// ...publicclassUserModel{    publicintId { get; set; }           publicstringName { get; set; }           publicstringEmail { get; set; }           publicstringPhoneNumber { get; set; }           publicstringAddress { get; set; }} | 
输出结果
FirstSample输出结果:

DISample输出结果:
http://localhost:5000/Home/DISample
| 1 | logger is null: False. | 
BodySample输出结果:
- JSON![]()  
- XML![]() 
Model 验证
Model Binding 也可以顺便帮忙验证字段数据,只要在字段的属性上面带上Validation Attributes,如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | usingSystem.ComponentModel.DataAnnotations;// ...publicclassUserModel{    [Required]    publicintId { get; set; }    [RegularExpression(@"\w+")]    [StringLength(20, MinimumLength = 4)]    publicstringName { get; set; }    [EmailAddress]    publicstringEmail { get; set; }    [Phone]    publicstringPhoneNumber { get; set; }    [StringLength(200)]    publicstringAddress { get; set; }} | 
然后在Action 加上判断:
Controllers\HomeController.cs
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | usingMicrosoft.AspNetCore.Mvc;namespaceMyWebsite.Controllers{    publicclassHomeController : Controller    {        // ...        publicIActionResult BodySample([FromBody]UserModel model)        {            // 由于 Id 是 int 类型,int 默认为 0            // 虽然带上了 [Required],但不是 null 所以算是有值。            if(model.Id < 1)            {                ModelState.AddModelError("Id", "Id not exist");            }            if(ModelState.IsValid)            {                returnOk(model);            }            returnBadRequest(ModelState);        }    }} | 
输入错误数据的输出结果:

.NET Core提供了很多的Validation Attributes,可以参考官网:System.ComponentModel.DataAnnotations
自定义Validation Attributes
如果.NET Core提供的Validation Attributes不够用还可以自己做。
例如上述范例的数据模型多了生日字段,需要验证年龄:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | usingSystem;usingSystem.ComponentModel.DataAnnotations;namespaceMyWebsite.Attributes{    publicclassAgeCheckAttribute : ValidationAttribute    {        publicintMinimumAge { get; privateset; }        publicintMaximumAge { get; privateset; }        publicAgeCheckAttribute(intminimumAge, intmaximumAge)        {            MinimumAge = minimumAge;            MaximumAge = maximumAge;        }        protectedoverrideValidationResult IsValid(objectvalue, ValidationContext validationContext)        {            vardate = Convert.ToDateTime(value);            if(date.AddYears(MinimumAge) > DateTime.Today                || date.AddYears(MaximumAge) < DateTime.Today)            {                returnnewValidationResult(GetErrorMessage(validationContext));            }            returnValidationResult.Success;        }        privatestringGetErrorMessage(ValidationContext validationContext)        {            // 有帶 ErrorMessage 的话优先使用            // [AgeCheck(18, 120, ErrorMessage="xxx")]            if(!string.IsNullOrEmpty(this.ErrorMessage))            {                returnthis.ErrorMessage;            }            // 自定义错误信息            return$"{validationContext.DisplayName} can't be in future";        }    }} | 
鸣谢:
https://www.cnblogs.com/snaildev/p/9112646.html
本文来自博客园,作者:{春光牛牛,yak},转载请注明原文链接:https://www.cnblogs.com/yakniu/p/16550968.html
欢迎各位大佬们评论指正
QQ讨论群:610129902 
 

 
                    
                
 
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号