簡體   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