在调用PUT(编辑)端点时,如何从模型中省略变量?

本文关键字:模型 中省 变量 PUT 调用 编辑 端点 | 更新日期: 2023-09-27 18:10:40

我有一个ASP。处理各种对象的。NET WEB API 2服务。我们使用这个服务来执行基本的CRUD功能。它们都很简单,但是当我试图编辑一个对象时,我遇到了一个问题。

我将让代码解释:

    [HttpGet]
    [Route("{companyId}")]
    public IHttpActionResult GetCompanyByCompanyId([FromUri] int companyId)
    {
        // get company
    }
    [HttpPost]
    [Route("")]
    public IHttpActionResult AddCompany([FromBody] CompanyDto companyModel)
    {
        // Insert a company
    }
    [HttpPut]
    [Route("{companyId}")]
    public IHttpActionResult UpdateCompany([FromUri] int companyId, [FromBody] Company companyModel)
    {
        // Update the company
    }

我所做的就是创建Company和CompanyDto模型。两者之间的唯一区别是CompanyDto不包含id。这样我们就可以发布对象,并让数据库告诉我们id将是什么。

创建公司对象之后,现在就有了Id。现在我们要编辑这个对象。我们将完整的Company对象传递给PUT方法,并让它覆盖所有值。但是,Company模型中有一个变量/属性是不允许更新的。显然,我可以在存储库层中省略传递给数据库的数据。但是,我不想让此服务的消费者感到困惑。我只想公开必需的或可编辑的参数。我们该怎么做呢?

以下是Company和CompanyDto模型供参考:

public class Company
{
    [Required]
    [Range(1, int.MaxValue)]
    public int CompanyId { get; set; }
    [Required]
    [MaxLength(20)]
    public string CompanyName { get; set; }
    [Range(1, int.MaxValue)]
    public int DataCenterId { get; set; }
 }
 public class CompanyDto
 {
    [Required]
    [MaxLength(20)]
    public string CompanyName { get; set; }
    [Required]
    [Range(1, int.MaxValue)]
    public int DataCenterId { get; set; }
 }

看,当我们POST CompanyDto时,我们提供了DataCenterId,但是当我们编辑Company对象时,我们不应该被允许编辑DataCenterId。当我们GET Company对象时,我们应该接收到所有3个属性。我是否需要制作第三个模型来实现这一目标,或者是否有数据注释可以帮助我实现这一目标?顺便说一下,我们没有使用EF。我们有自己的内部ORM解决方案

在调用PUT(编辑)端点时,如何从模型中省略变量?

为了使解决方案完整并使自动生成的帮助达到最大的正确性,是的,您必须创建第三个dto对象,该对象只包含客户端实际允许编辑的那些属性。这是使用您拥有的那些URI向消费者传递正确消息的唯一方法。

但是,如果您能够并且愿意更改URI,并且如果它们恰好是您的域的更具描述性的变体,我还建议您考虑公司ID是否可以驻留在URI本身中。这样你就可以把它从dto中取出来,而不必为此而创建不同的类。

同样,put方法应该将CompanyDto对象作为参数,因为公司ID已经在URI中提供了。否则,如果URI公司ID与请求中的company对象中的公司ID不同,用户期望发生什么?

还请注意,您不应该像这样将这些dto交付到业务逻辑层中,我怀疑您现在正在基于Company对象作为put -方法的参数进行交付。相反,业务层应该定义另一个对象,并将WebAPI对象映射到该对象,包括来自URI的id。这样,对底层业务层DTO的更改将不会破坏实际的公共API,即WebAPI。

我以前的公司有一个非常漂亮的系统,我今天还在使用,我们将所有传入类命名为请求类,即CompanyRequest,并将所有传出类命名为响应类,即CompanyResponse。通过这种方式,响应可以使用数据中心的名称进行充实,因为在查看公司实体时几乎总是需要这样做。然后,该名称不应该出现在请求对象上,因为不应该通过编辑公司来编辑该名称。