【问题标题】:What is wrong with my Web API routing?我的 Web API 路由有什么问题?
【发布时间】:2017-07-28 22:38:40
【问题描述】:

我有一个带有以下两个动作签名的控制器。我正在使用传统路由与属性路由,因为我一直在尝试任何方法来完成这项工作,而传统路由解决了 2 个问题中的 1 个。

[HttpGet]
[ResponseType(typeof(IEnumerable<EmployeeBindingModel>))]
public async Task<IHttpActionResult> ReadAll()

当我从 Postman 使用 URL:http://localhost:53093/api/Employees/ReadAll 调用它时,我得到以下 JSON:

{
  "Message": "The request is invalid.",
  "MessageDetail": "The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Threading.Tasks.Task`1[System.Web.Http.IHttpActionResult] Read(Int32)' in 'AcmeSoft.WebApi.Controllers.EmployeesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."
}

另一个动作是:

[HttpGet]
[ResponseType(typeof(EmployeeBindingModel))]
public async Task<IHttpActionResult> Read(int id)

当我用这个 URL 调用它时:http://localhost:53093/api/Employees/Read/5 我得到了预期的员工 JSON 记录。

我的路由在WebApiConfig中设置如下:

//config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new {id = RouteParameter.Optional});

我一直使用这个标准样板,今天是我第一次收到错误。为什么在地球上没有参数的动作会期望一个? ReadAll 从来没有参数,所以它甚至不是什么鬼。我已经删除了所有 ASP.NET 临时文件,没有任何变化。

【问题讨论】:

  • 包含控制器以完成示例。现在我们可以假设它是员工控制器,但这仍然是一个猜测。
  • @Nkosi I 所有影响控制器中路由的是动作方法签名及其属性,它们都包含在内。
  • 您正在使用基于约定的路由,并且在控制器中有两个 HttpGet 操作。根据显示的 Web API 配置,它们不应该工作,因为它们会相互冲突。因此,这意味着问题中省略了一些细节,这些细节可用于更好地评估您的问题并提供解决方案。提供可用于重现问题的minimal reproducible example
  • Why on Earth would an action without a parameter expect one? 路由表抓取第一个匹配请求的路由。如果有多个路由匹配,则可能是请求与错误路由匹配的冲突。
  • @Nkosi,如果你能解释一下,在没有任何重定向的情况下,动作实现如何影响路由,我向你脱帽致敬。 Ankush 在下面的回答只用我提供的必要细节解决了这个问题。安库什是通灵者还是什么?如果缺少任何相关内容,这就是我调用 api 的方式以及我使用的请求动词,即 GET。

标签: asp.net asp.net-mvc asp.net-web-api asp.net-mvc-5 asp.net-mvc-routing


【解决方案1】:

在 WebApiConfig 中进行更改:

//config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new {id = RouteParameter.Optional});

在 routeTemplate 中也使用操作

【讨论】:

  • 头上的钉子!我假设操作调用选择了它可以匹配的第一个HttpGet 操作,即带有id 的操作,用于成功调用,但在没有定义参数或类似的东西的情况下阻止了另一个HttpGet 操作。这让我想知道为什么默认路由模板省略了{action}。我们是否应该对每个请求动词只有一个动作,并根据该动作选择动作?
  • @ProfK 是的。默认的基于约定的路由模板最初是为 RESTful Web API 设计的,每个 HTTP 方法一个操作。该框架仍然允许灵活地对其进行更改以满足您的特定需求。
  • 谢谢,@Nkosi。这似乎有点限制,但它可能是新的属性路由和核心 Web API 留下的那些东西之一。
猜你喜欢
  • 2018-07-13
  • 1970-01-01
  • 2014-11-27
  • 2013-08-30
  • 2018-03-06
  • 1970-01-01
相关资源
最近更新 更多