繁体   English   中英

ASP.NET CORE Model 绑定:为什么 DTO 的 getter 在设置值之前被运行时调用?

[英]ASP.NET CORE Model binding: Why the getter of DTO is get called by runtime before the value is set?

我正在尝试使用getter来验证DTO的属性,如果属性无效则抛出异常,示例代码如下:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }


    [HttpPost("test")]
    public IActionResult Post([FromBody] Foo f)
    {
        return Ok(f.Bar.Count == 1);
    }
}

public class Foo
{
    private List<string> _bar;
    public List<string> Bar
    {
        get
        {
            if (_bar == null || _bar.Count == 0) throw new System.Exception("at lease one element is required!");
            return _bar;
        }
        set
        {
            _bar = value;
        }
    }
}

使用 curl 调试 api

curl --location --request POST 'http://localhost:5000/WeatherForecast/test2' --header 'Content-Type: application/json' --data-raw '{
    "Baz":"HelloWorld"
}'

在 API 调试过程中,我观察到 setter 是用一个空的 list 值调用的,即使相应的输入有值,然后是 getter。 结果,由于列表为空,getter 引发了异常。

似乎 model 绑定行为在enumerable类型和non-enumerable类型之间存在一些差异(如果我将BarList<string>更改为string ,我将在 setter 中获得值);

问题:

  1. 有什么办法可以配置asp.net核心以non-enumerable enumerable类型的属性,我想在getter而不是其他地方进行验证

在您的请求 model Foo中,您断言Bar将是字符串的集合(例如,数组)。 但是,在您的 curl 请求中,您将Bar设置为单个字符串,而不是包含一个字符串的数组。

相反,您应该使用curl --location --request POST 'http://localhost:5000/WeatherForecast/test2' --header 'Content-Type: application/json' --data-raw '{ "Bar": ["HelloWorld"] }'

如果您想接受Bar的字符串或数组,则不能将 DTO class 与[FromBody]一起使用。 相反,您必须编写自己的逻辑来确定请求正文中的数据类型,然后手动将 JSON 数据解析为适当的 model。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM