繁体   English   中英

空数组的默认值数据注释

[英]Default value data annotation for empty array

我正在创建一个 .NET Core Web API 并想调用端点提交客户订单。 客户 ID 作为路由参数出现。 在请求正文中,可以发送对象数组。 每个 object 都包含产品 ID 及其数量。 但是这个字段是可选的,空订单也是可能的(产品可以稍后添加)。

所以我从这个 DTO 开始

public class CreateCustomerOrderByIdDto
{
    [FromRoute]
    public uint Id { get; set; }

    [FromBody]
    public OrderPosition[] OrderPositions { get; set; }
}

public class OrderPosition
{
    [Range(1, uint.MaxValue)]
    public uint ProductId { get; set; }

    [Range(1, uint.MaxValue)]
    public uint Amount { get; set; }
}

此请求 DTO 应使OrderPositions字段可选,但在添加项目时,该项目的两个属性都是必需的。 如果丢失,我想为OrderPositions设置一个默认值,所以我认为这个数据注释会做到这一点

[DefaultValue(new OrderPosition[0])]

不幸的是,我收到此错误消息

属性参数必须是属性参数类型的常量表达式、'typeof()' 表达式或数组创建表达式

那么如何将该字段标记为可选并设置默认值呢?

当不传递订单位置时,数组将被转换为空的,这样我就可以避免 null 检查并使用从未运行过的循环

也许您可以使用List<OrderPosition>而不是数组。 然后在构造函数中将其初始化为空列表

public class CreateCustomerOrderByIdDto
{
    public CreateCustomerOrderByIdDto()
    {
        this.OrderPositions = new List<OrderPosition>();
    }
    [FromRoute]
    public uint Id { get; set; }

    [FromBody]
    public List<OrderPosition> OrderPositions { get; set; }
}

public class OrderPosition
{
    [Range(1, uint.MaxValue)]
    public uint ProductId { get; set; }

    [Range(1, uint.MaxValue)]
    public uint Amount { get; set; }
}

与 hphp 的答案类似,您可以像使用任何 c# class 一样设置默认值:

public class CreateCustomerOrderByIdDto
{
    [FromRoute]
    public uint Id { get; set; }

    [FromBody]
    public OrderPosition[] OrderPositions { get; set; } = new OrderPosition[0]; // auto-initialize it here. 

    // alternatively you can use a constructor, but I prefer setting the property like above
    public CreateCustomerOrderByIdDto
    {
        OrderPositions = new OrderPosition[0];
    }
}

public class OrderPosition
{
    [Range(1, uint.MaxValue)]
    public uint ProductId { get; set; }

    [Range(1, uint.MaxValue)]
    public uint Amount { get; set; }
}

如果您不喜欢这些想法并且您正在使用 Newtonsoft.Json,您还可以利用序列化事件,并对这些事件执行默认值设置器: https://www.newtonsoft.com/json/help/html /SerializationCallbacks.htm

arrays 的问题在于它具有固定长度。 您可以使用Array.Resize()调整数组的大小,但这也需要固定长度。

更好的方法是使用 List 而不是数组:

public class CreateCustomerOrderByIdDto
{
    [FromRoute]
    public uint Id { get; set; }

    [FromBody]
    public List<OrderPosition> OrderPositions { get; set; }
}

默认情况下,列表 object OrderPositions将具有null值; 这是表示列表中不存在任何项目的好方法。

如果您仍然需要默认列表为空,而不是 null,您可以设置默认值如下:

public List<OrderPosition> OrderPositions { get; set; } = new List<OrderPosition>();

暂无
暂无

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

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