向ASP.NET Web API Controller添加显式操作路由

use*_*100 18 c# asp.net rest asp.net-mvc asp.net-web-api

我有一个ASP.NET Web API项目,ApiController它为User端点提供以下操作:

GET /api/User
POST /api/User
DELETE /api/user
Run Code Online (Sandbox Code Playgroud)

我想提供以下端点:

GET /api/user/metrics
Run Code Online (Sandbox Code Playgroud)

但是,当我像这样定义控制器动作时:

[HttpGet]
public HttpResponseMessage Metrics()
{
    return null;
}
Run Code Online (Sandbox Code Playgroud)

我收到Multiple actions were found that match the request错误消息.

我理解这违反了"纯"REST API的定义,但这就是我想要做的.我想我必须通过映射HTTP路由来解决这个问题,但是我尝试了一些路由而且我无法让它工作.我的路线应该是什么样的?

clh*_*ian 19

默认路由不包括操作.

routes.MapHttpRoute(
    name: "API Default",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)

它根据路由器中的控制器,HTTP谓词和参数或缺少参数来选择操作.因此,它找到了正确的控制器并寻找没有参数的GET动作.它找到两个.

您应该添加包含该操作的其他路由.这可以通过Kiran提到的基于属性的路由或基于约定的路由来完成.对于基于约定的路由,路由通常放在Application_start()方法中WebApiConfig.cs.更具体的路线在一般路线之前,所以你的路线看起来像这样:

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

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

  • 我的配置与此完全相同并出现此错误:{"消息":"找不到与请求URI匹配的HTTP资源'http://localhost:53873/api/ControllerName/4'.","MessageDetail": "在控制器'ControllerName'上找不到与名称'4'匹配的操作."} (2认同)

Kir*_*lla 17

如果您使用的是Web API 2,我建议使用属性路由,这样可以使这些场景的体验更加轻松.

您可以继续使用默认的常规路由来处理大多数场景,但可以在需要的位置使用属性路由,就像在当前场景中一样.

以下示例演示了类似的情况:

http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/WebApiAttributeRoutingSample/WebApiAttributeRoutingSample/Controllers/Api/CustomersController.cs