C# 在API C中何时使用模型作为url参数的参数#

C# 在API C中何时使用模型作为url参数的参数#,c#,asp.net,api-design,C#,Asp.net,Api Design,我在控制器中有一个返回对象列表的方法。控制器的实现并不重要。该方法称为GetAllTestsByLocationAndPollTypeId,并返回“测试”对象列表。GET包含4个参数,一个locationId,pollTypeId,itemsToLoad和一个字符串,用于搜索。我希望添加更多参数,并且觉得在url中传递6个对象有点过分。方法签名如下所示: [HttpGet] public IHttpActionResult GetAllTestsByLocationIdAndPollTypeId

我在控制器中有一个返回对象列表的方法。控制器的实现并不重要。该方法称为
GetAllTestsByLocationAndPollTypeId
,并返回“测试”对象列表。GET包含4个参数,一个
locationId
pollTypeId
itemsToLoad
和一个字符串,用于
搜索。我希望添加更多参数,并且觉得在url中传递6个对象有点过分。方法签名如下所示:

[HttpGet]
public IHttpActionResult GetAllTestsByLocationIdAndPollTypeId(int locationId, int pollTypeId, int itemsToLoad = 8, string search = "")
我应该传入一个包含当前用于参数的值的模型吗

编辑:我不能执行
[HttpPost]
,因为
POST
请求不会被缓存,因此可能会很昂贵,在这种情况下会很昂贵


编辑:我使用可选参数解决了查询字符串中的过滤器问题,以减少传入的内容数量

这完全取决于您,但当参数增加时是的&具有较大的大小标头大小可以超过,因为它是
HttpGet
,其中数据作为查询字符串参数在标头中发送

您可以尝试
HttpPost
,因为它在正文中发送数据,如果数据通过https,还使用class&不显示参数值:

[HttpPost]
public IHttpActionResult GetAllTestsByLocationIdAndPollTypeId([FromBody]TestLocation request)
在这里,我假设您可以创建class
TestLocation
或任何您喜欢的带有所需参数name的公共属性的名称

现在您需要在
stringify
之后发送类的
JSON
对象,比如
{'locationId':1,'pollTypeId':1,'itemsToLoad':10,'search':'your text'}
&将ajax更改为post。既然你已经离开了从ajax打电话的方式,我就把它留给你

更新


根据@PanagiotisKanavos(未缓存帖子)的反馈和您提供的查询字符串不长的信息,您可以尝试添加如下路由:

config.Routes.MapHttpRoute("MyRoute", "{controller}/{locationId}/{pollTypeId}/{itemsToLoad}/{search}", new { controller = "Region", action = "GetCountries" })
或者,如果路由/参数对于操作方法是唯一的,则在控制器级别添加属性:

[Route("GetAllTestsByLocationIdAndPollTypeId/{locationId}/{pollTypeId}/{itemsToLoad}/{search}")]
[HttpGet]
public IHttpActionResult GetAllTestsByLocationIdAndPollTypeId(int locationId, int pollTypeId, int itemsToLoad = 8, string search = "")
现在,您的api调用可以如下所示:


您可以尝试路由和查询的组合。e、 g.{LocationId}/{pollType}/Tests?itemsToLoad=N&search=X,正如@KirkLarkin所建议的那样

你所说的“model”是什么意思?您可以使用从查询参数中获取其值的强类型模型类。此外,为什么不使用路由来提供参数呢?例如,
{pollType}/{LocationId}/tests
将是一个非常有用的途径。是的,因此一个强类型的类,使用参数作为属性或字段,并将其传递到请求体中。我个人的意见是,发布。如果你真的关心性能,那么你可以用一种巧妙的方法来达到同样的效果。调用api时从客户端严格使用(您的对象)。在api内部,将其作为一个普通字符串进行反序列化说服自己的最好方法是看看什么是REST-这将帮助您知道何时使用URL参数以及何时发布数据。虽然我同意参数的数量,但另一部分让我有些困惑。对于大多数用例来说,URL大小限制是相当高的,使用POST作为GET请求(当您真的需要传递一些大对象时,例如在处理过滤器时,有其他成熟的模式),这是一种糟糕且误导性的设计。我们使用过滤器。我们的API设计不是最好的,我们的控制器很大。我们的控制器所做的很多事情都可以重构,模型可以作为重构和删除所有不同参数组合的一种方式。这也不仅仅是违反约定
POST
无法缓存,这将使此调用非常昂贵。这都有点主观,但我的建议是使用路由和查询的组合。e、 g.
{LocationId}/{pollType}/Tests?itemsToLoad=N&search=X
。我喜欢这种路由方法。我认为目前我们仍坚持使用标准的查询字符串,但我将把它带到团队中,并在将来使用它。非常感谢你