【问题标题】:Dto in GET request never appears nullGET 请求中的 Dto 永远不会出现 null
【发布时间】:2019-11-19 13:20:42
【问题描述】:

我在 Asp.Net Core 2.2 中有一个 GET 端点,我想默认返回所有记录,如果提供了任何查询,那么我将返回一个搜索查询响应。在这里,即使没有提供查询参数,我的查询 Dto 也永远不会为空。当没有提供查询参数时,我想保持 Dto 为空。

我的请求 Dto-

public sealed class SearchQueryDto
{
    public SearchQueryDto()
    {
        Limit = 10;
        Offset = 0;
    }

    public string Query { get; set; }
    public string PhoneNumber { get; set; }
    public string ClassificationId { get; set; }
    public int Offset { get; set; }
    public int Limit { get; set; }
}

我的端点-

[HttpGet]
public async Task<IActionResult> GetAllRecords([FromQuery] [CanBeNull] SearchQueryDto request)
{
    if (request != null) // always not null
    {
        return Ok(await _service.Search(request));
    }
    return Ok(await _service.GetAll());
}

在这里,当没有提供查询参数但它总是显示为已初始化时,我期望请求为空。

【问题讨论】:

  • 你们如何提供搜索参数?
  • 只是一个猜测,你是否有机会发送带有空值的 json 而不是发送 null
  • @ChetanRanpariya 调用 like- api/product/getall 和 api/product/getall?Query=sample&Limit=100&Offset=0

标签: c# asp.net-core asp.net-core-webapi


【解决方案1】:

The docs lie:

路由数据和查询字符串值仅用于简单类型。

这根本不是真的。另请参阅Bind query parameters to a model in ASP.NET Core,它可以正常工作。

这部分文档是真的:

发生模型绑定时,使用公共默认构造函数实例化类。

因此,模型类将始终被实例化。除非它是从正文绑定的,并且正文是空的、损坏的或内容类型错误,但那是另一回事了。

在您的情况下,只需检查模型是否没有设置任何属性:

public sealed class SearchQueryDto
{
    private const int DefaultLimit = 10;
    private const int DefaultOffset = 0;

    public string Query { get; set; }
    public string PhoneNumber { get; set; }
    public string ClassificationId { get; set; }
    public int Offset { get; set; } = DefaultOffset;
    public int Limit { get; set; } = DefaultLimit;

    public bool IsDefault
    {
        get
        {
            return string.IsNullOrEmpty(Query)
                && string.IsNullOrEmpty(PhoneNumber)
                && string.IsNullOrEmpty(ClassificationId)
                && Offset == DefaultOffset
                && Limit == DefaultLimit;
        }
    }   
}

然后在你的控制器中:

if (!request.IsDefault)
{
    // ...
}

【讨论】:

  • 解释得很好!以更清洁的方式解决我的问题。现在 IsDefault 参数出现在我不希望它在那里的招摇中。
  • 您可以使用 JsonIgnore 来防止它被序列化和记录。或者将属性设为internal 而不是public
【解决方案2】:

你可以设置默认为空

[HttpGet] public async Task<IActionResult> GetAllRecords([FromQuery] SearchQueryDto request = null)

【讨论】:

  • 这并不能解决问题。请参阅@CodeCaster 的回答解释了为什么。
【解决方案3】:

虽然你不传递查询字符串,但是模型会绑定默认值,所以你不能得到空值。

在这种情况下,你可以像下面这样修复它:

[HttpGet]
public async Task<IActionResult> GetAllRecords([FromQuery]SearchQueryDto request)
{
    var query = Request.QueryString.HasValue;
    if (query)
    {
        return Ok(await _service.Search(request));
    }
    return Ok(await _service.GetAll());
}

【讨论】:

    猜你喜欢
    • 2014-06-17
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2012-01-05
    相关资源
    最近更新 更多