[英]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
類型之間存在一些差異(如果我將Bar
從List<string>
更改為string
,我將在 setter 中獲得值);
問題:
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.