解决触发 web api 操作方法的问题

Troubleshoot to trigger web api action method

我在我的网络 api 项目上工作。

我在控制器中有两个获取操作方法。

这里是控制器:

namespace Playground.Web.Controllers.API
{
    [RoutePrefix("api/DamageEvent/{actionType}")]
    public class DamageEventController : ApiController
    {
        #region API methods
        [HttpGet]
        public async Task<IHttpActionResult> GetDamageEvent(int damageEventId = 0)
        {
           //some logic 
        }
        [HttpGet]
        [Route("{ddd:int}")]
        public async Task<IHttpActionResult> GetDamageEvent2(int ddd = 0)
        {
           //some logic 
        }
        #endregion
    }
}

此处 WebApiConfig 定义:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Formatters.JsonFormatter.SerializerSettings.DateFormatString = "dd/MM/yyyy";
    }
}

这里是URL在fiddler compose中触发webapi动作的例子:

http://localhost/playground/api/DamageEvent/GetDamageEvent2/?ddd=22

我预计 URL 以上 GetDamageEvent2 网络 api 操作将被触发。但是 GetDamageEvent 操作方法被触发了。

为什么 GetDamageEvent2 没有触发?知道我错过了什么吗?

================================更新==== ============================

在我从 Nkosi

红色回答之后

我对我的代码做了一些更改,我添加到 class WebApiConfig 新路由:

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

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

这里是动作类型的变化:

namespace Playground.Web.Controllers.API
{
    [RoutePrefix("api/DamageEvent")]
    public class DamageEventController : ApiController
    {
        #region API methods
        [HttpGet]
        [Route("GetDamageEvent/{damageEventId}")]
        public async Task<IHttpActionResult> GetDamageEvent(int damageEventId = 0)
        {
           //some logic 
        }
        [HttpGet]
        [Route("GetDamageEvent2/{ddd}")]
        public async Task<IHttpActionResult> GetDamageEvent2(int ddd = 0)
        {
           //some logic 
        }
        #endregion
    }
}

在我进行上述更改后,我尝试触发这两个操作并且成功了。

但现在的问题是当我尝试在另一个控制器中调用另一个动作时,例如:

http://localhost/playground/api/Contracts/1

我收到 404 错误。

所以我猜错误是因为新的路线模板。

所以我的问题是如何修复上述错误并仅在 URI 尝试访问 DamageEventController 时才考虑新的路由模板?

您混合了属性路由和基于约定的路由。

没有任何内容与您的 RoutePrefix 匹配,因为控制器中没有同时具有 {actionType} {ddd} 模板的操作。

但是你说的 URL...

api/DamageEvent/GetDamageEvent2/?ddd=22

...匹配路由 table 中 GetDamageEvent 的基于 DefaultApi 约定的路由,因为它没有 [RouteAttribute] 并且默认返回约定...

api/{controller=DamageEvent}/{id=GetDamageEvent2/?ddd=22}

查看 Routing in ASP.NET Web API 了解基于约定的路由。

还有Attribute Routing in ASP.NET Web API 2

Each entry in the routing table contains a route template. The default route template for Web API is "api/{controller}/{id}". In this template, "api" is a literal path segment, and {controller} and {id} are placeholder variables.

When the Web API framework receives an HTTP request, it tries to match the URI against one of the route templates in the routing table. If no route matches, the client receives a 404 error. For example, the following URIs match the default route:

/api/DamageEvent
/api/DamageEvent/1
/api/DamageEvent/GetDamageEvent2/?ddd=22

Once a matching route is found, Web API selects the controller and the action:

  • To find the controller, Web API adds "Controller" to the value of the {controller} variable.
  • To find the action, Web API looks at the HTTP method, and then looks for an action whose name begins with that HTTP method name. For example, with a GET request, Web API looks for an action that starts with "Get...", such as "GetDamageEvent". This convention applies only to GET, POST, PUT, and DELETE methods. You can enable other HTTP methods by using attributes on your controller. We’ll see an example of that later.
  • Other placeholder variables in the route template, such as {id}, are mapped to action parameters.

要让您指定的路线生效,您需要更新路线模板。要么属性路由,要么给路由添加新的约定路由table