ASP.如何排除属性从DTO对象基于put/get/post/delete

本文关键字:对象 put DTO post get delete 何排除 排除 属性 ASP | 更新日期: 2023-09-27 18:10:56

我正在做一个ASP。. NET web api(第一次!)对于每个数据库对象,我都创建了一个DTO对象来平面化对象。我使用automapper来映射这些对象。我想只使用一个DTO对象的所有请求类型(get/put/post/delete)。

简化的例子:

public class ProductDB
{
    public int ProductId { get; set; }
    public string Name { get; set; }
}
public class ProductDTO
{
    [JsonIgnore] -- only in case of a put/post/delete request
    [XmlIgnore] -- only in case of a put/post/delete request
    public int ProductId { get; set; }
    public string Name { get; set; }
}

如果我执行HttpGet来获取产品列表,我希望在响应中包含ProductId。响应类型将是IEnumerable ProductDTO,包括productid。

如果我执行HttpPut,请求将是:https://base-url/products/id,以ProductDTO为主体。但是,在本例中,我不希望ProductId包含在ProductDTO中。

我知道如何排除属性,通过用[JsonIgnore]和[XmlIgnore]属性装饰它们。然而,这总是将它们排除在外。我想有条件地排除它们,基于请求是HttpGet/HttpPost/HttpPut/HttpDelete。

这可能吗?或者是否有另一种方法可以根据请求类型从DTO中排除属性?

ASP.如何排除属性从DTO对象基于put/get/post/delete

如果我执行HttpPut,请求将是:https://base-url/products/id,以ProductDTO为主体。但是,在本例中,我不希望ProductId包含在ProductDTO中。

技术上不需要,因为我们只是在讨论请求而不是响应。取决于客户端发送的内容。如果客户端发送这个JSON:

{
    "Name" : "Some Value"
}

那么就模型绑定器而言,这是有效的。它将创建一个具有Name属性集的ProductDTO实例。在服务器端代码中,您可以根据路由中的id设置ProductId属性,执行映射,然后您就拥有了域对象。

客户端不需要知道他们可以在JSON中设置ProductId属性。如果他们设置了一个,它只会被你代码中的路由值无声地覆盖,并且基本上被忽略。当然,如果他们在DTO上没有这样的属性时设置了一个,那么它也会被简单地忽略。

对于传出的 dto,您需要对序列化器包含和不包含的内容进行微调。但是对于传入的 DTO,您有更多的回旋余地,因为您实际上并没有以任何方式向消费系统宣传DTO的形状。

我唯一一次看到这个问题是在使用工具生成API文档时。例如,像Swashbuckle这样的东西将在API文档中包含该属性。这并不理想。在这种情况下,我发现最短的路径是为不同的操作创建单独的dto。这并不罕见,一些MVC框架甚至专门设计为一个模型匹配一个请求。