【发布时间】:2022-01-14 14:46:00
【问题描述】:
我正在尝试寻找“最佳”方式来检查请求 URL 中的数据与请求正文中的数据之间的一致性。
例如,假设我们有这个 PUT 端点:
https://host:port/foo/bar/{carId}
我可以将 Car 对象作为 body 传递:
class Car {
string CarId { get; set; }
string Brand { get; set; }
int MaxSpeed { get; set; }
...
}
现在,在我的控制器中,我有这样的东西:
[HttpPut("foo/bar/{carId}")]
public async Task updateCar([FromRoute] string carId, [FromBody] Car car) {
...
}
而且我想确保路由中的 carId 与正文中的 CarId 属性匹配。
实现这一目标的“最佳”方法是什么?当然,我可以简单地在 body 控制器中使用 if 进行检查,但由于这是一个验证任务(或者至少我认为是这样),我希望在我的验证层中有这个逻辑。
到目前为止的个人想法
好了,问题结束了,这里我就放一些我尝试过或者想尝试的想法。
我有一个自定义操作过滤器来检查验证,我正在尝试使用它来看看我是否可以在那里做某事,或者只在我需要的地方添加另一个自定义操作过滤器想检查连贯性,但这看起来不太乐观。
目前我看到在动作过滤器中我可以通过context.ActionArguments 属性访问控制器方法参数,但我不知道如何检查这些参数是否是“绑定参数”(即有一些[FromXXX] 属性)。如果我能做到这一点,也许我可以检查是否有同名的参数(或同名的属性),然后比较它们的值。但这似乎非常麻烦且不一致。
我已经阅读了有关自定义活页夹的内容,但我仍处于摸索阶段(我希望在接下来的几个小时内能学到更多东西):它们是一种可能的解决方案吗?
【问题讨论】:
-
最好的办法是不要把carId放在一个路由里。只是因为好奇,为什么需要两次 put carId?
-
@Serge 因为一个是汽车模型的一部分,一个是唯一识别汽车的路线的一部分。所以恕我直言,两者都应该在场。我也读过something 关于这个。
-
感谢您的回答和链接。但是这篇文章对我来说看起来很奇怪。它是一个人写的,除了“Hello world”之外,他从未参与过任何严肃的项目。恕我直言,您应该忘记这篇文章,这并不严重。
-
@Serge 感谢您的澄清!那么我该怎么做呢?我应该从正文还是从路线中删除重复的信息?还是我应该简单地用路线中的信息“覆盖”正文中的信息?你也可以给我一些资源来学习这些设计的东西吗?我也尝试阅读MS post关于 REST API 设计,但似乎没有谈论这个。
-
您不能从body中删除,因为您不仅需要carId,因此只需删除“[FromRoute] string carId”并制作您的路线[Route("~/foo/bar")]。例如,如果不是您的 scholl 项目,我认为您也不需要 Put 或 Delete 。我总是只使用 Get 或 Post 并且认为将这些词放到路由中也没有任何意义。如果有人告诉你休息原则,不要听,这只是一本教科书。真正的控制器可以有大约一百个动作,你肯定不能只使用 4 种方法来实现这些动作。你的动作应该有有意义的名字。
标签: c# asp.net-core validation .net-core asp.net-core-webapi