Asp.Net Core 模型绑定

概述

ASP.NET Core MVC 的模型绑定会把Http Request 中的数据,以映射的方式对应到相应的参数中去.

模型绑定

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

1
2
3
4
5
6
7
8
9
10
11
12
using Microsft.AspNetCore,Mvc;

namespace Caty.Web.Controllers
{
public class LoginController : Controller
{
public IActionResult Index(string username, string password)
{
return Content($"username:{username},password:{password}");
}
}
}

其中username和password就是从Http Requset的数据被绑定的模型参数.

默认的模型绑定会从Http Requset的三个地方取值(优先级由上到下)

如果三者都传入,取值的优先顺序为Form>Route>Query

绑定属性

除了上面提到的三个默认的绑定来源外,还可以通过模型绑定属性从Http Request的其他地方中绑定参数,有以下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来进行模型绑定,需要在MVC服务中加入XmlSerializerFormatters.

    Startup.cs

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

    这不是从Http Requset取值,而是从DI容器取值.DI默认是构造器注入,但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
33
34
public class UserController:Controller
{
public IActionResult HeaderSample([FromHeader]string header)
{
return Content($"header:{header}");
}
public IActionResult FormSample([FromForm]string form)
{
return Content($"form:{form}");
}
public IActionResult IdSample([FromRoute]string id)
{
return Content($"id:{id}");
}
public IActionResult QuerySample([FromQuery]string query)
{
return Content($"query:{query}");
}
public IActionResult DISample([FromServices] ILogger<UserController> logger)
{
return Content($"logger is null:{logger == null}");
}
public IActionResult BodySample([FromBody]UserModel user)
{
return Ok(model);
}
}

public class UserModel
{
public string Code { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}

模型验证

模型绑定也可以验证模型,需要在模型的属性上面带上 ValidationAttributes.

UserModel.cs

1
2
3
4
5
6
7
8
9
10
11
12
public class UserModel
{
[Required]
public string Code { get; set; }

[RegularExpression(@"\w+")]
[StringLength(20, MinimumLength = 4)]
public string Name { get; set; }

[EmailAddress]
public string Email { get; set; }
}

UserController.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using Microsoft.AspNetCore.Mvc;

namespace MyWebsite.Controllers
{
public class UserController : Controller
{
public IActionResult BodySample([FromBody]UserModel model)
{
if (ModelState.IsValid)
{
return Ok(model);
}
return BadRequest(ModelState);
}
}
}

自定义模型验证

UserModel.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class UserModel
{
[Required]
public string Code { get; set; }

[RegularExpression(@"\w+")]
[StringLength(20, MinimumLength = 4)]
public string Name { get; set; }

[EmailAddress]
public string Email { get; set; }

[AgeCheck(18,100)]
public DataTime BirthDate { get; set; }
}

AgeCheckAttribute.cs

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
using System;
using System.ComponentModel.DataAnnotations;

namespace Caty.Web.Attributes
{
public class AgeCheckAttribute : ValidationAttribute
{
public int MinimumAge { get; private set; }
public int MaximumAge { get; private set; }

public AgeCheckAttribute(int minimumAge, int maximumAge)
{
MinimumAge = minimumAge;
MaximumAge = maximumAge;
}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var date = Convert.ToDateTime(value);

if (date.AddYears(MinimumAge) > DateTime.Today
|| date.AddYears(MaximumAge) < DateTime.Today)
{
return new ValidationResult(GetErrorMessage(validationContext));
}

return ValidationResult.Success;
}

private string GetErrorMessage(ValidationContext validationContext)
{
// 有带 ErrorMessage 的話优先使用
// [AgeCheck(18, 100, ErrorMessage="xxx")]
if (!string.IsNullOrEmpty(this.ErrorMessage))
{
return this.ErrorMessage;
}

// 自定义错误信息
return $"{validationContext.DisplayName} can't be in future";
}
}
}

Asp.Net Core 模型绑定
http://blog.chcaty.cn/2019/06/26/asp-net-core-mo-xing-bang-ding/
作者
caty
发布于
2019年6月26日
许可协议