首页 > 解决方案 > C# REST API 控制器:具有 2 个不同操作的相同路由

问题描述

使用以下路线时:

        config.Routes.MapHttpRoute(
            name: "new_device",
            routeTemplate: "api/v1/devices",
            defaults: new { controller = "Devices", action = "new_device" }
        );

        config.Routes.MapHttpRoute(
            name: "devices_list",
            routeTemplate: "api/v1/devices",
            defaults: new { controller = "Devices", action = "devices_list", httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
        );

控制器如下所示:

public class DevicesController : ApiController
{
    [HttpPost]
    [ResponseType(typeof(IHttpActionResult))]
    [Route("api/v1/devices")]
    [ActionName("new_device")]
    [ValidateModel]
    public IHttpActionResult NewDevice([System.Web.Http.FromBody] Device device )
    {
         ...
    }

    [HttpGet]
    [ResponseType(typeof(IHttpActionResult))]
    [Route("api/v1/devices")]
    [ActionName("devices_list")]
    [ValidateModel]
    public List<Device> GetAllDevices()
    {
        ...
    }

我的期望是路由器会根据使用的 HttpMethod 找到正确的路由,因为即使它使用相同的 URI,它也使用不同的 HttpMethod。

但相反,它失败了以下内容:

"Message": "请求的资源不支持 http 方法 'GET'。"

我的猜测是因为它找到了与 URI 的匹配,然后检查方法是否相同。

有没有办法通过 REST 指南来实现使用具有不同 Http 方法的相同 URI?我错过了什么吗?

标签: c#asp.net-mvcrestowin

解决方案


好的,我检查你的整个代码。我认为您正在尝试以复杂的方式实现呼叫。

以下代码用于配置:

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

        // Web API routes
        config.MapHttpAttributeRoutes();

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

以下是您的控制器代码:

public class DevicesController : ApiController
{
    [HttpPost]
    [ResponseType(typeof(IHttpActionResult))]       
    [ActionName("newDevice")]

    public IHttpActionResult NewDevice([System.Web.Http.FromBody] Device device)
    {
        return null;
    }

    [HttpGet]
    [ResponseType(typeof(IHttpActionResult))]        
    [ActionName("devices_list")]

    public List<Device> GetAllDevices()
    {
        return null;
    }
}

我删除了 ValidateModel。我认为这是您的自定义属性或与内置的 nuget 包有关。

无论如何,使用 Postman 或任何 HTTP 客户端工具执行调用。它应该可以工作,因为它最终使用上述代码工作。

示例调用:

https://localhost:44370/api/v1/devices/devices_list => 获取。
https://localhost:44370/api/v1/devices/newDevice => 发布。提供主体作为对象的后期调用。


推荐阅读