【问题标题】:GET verb not calling the correct actionGET 动词没有调用正确的动作
【发布时间】:2018-04-28 05:08:53
【问题描述】:

所以我直接从 MS .NET 教程中抓取了这个控制器代码,它运行良好:

public class ProductsController : ApiController
{
    Product[] products = new Product[]
    {
        new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
        new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
        new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
    };

    public IEnumerable<Product> GetAllProducts()
    {
        return products;
    }

    public IHttpActionResult GetProduct(int id)
    {
        Console.WriteLine("id = " + id);
        var product = products.FirstOrDefault((p) => p.Id == id);
        if (product == null)
        {
            return NotFound();
        }
        return Ok(product);
    }
}

在同一个命名空间中,我创建了 2 个自己的控制器,它们都显示相同的问题 - 只有第一个操作 (GetAll*()) 响应 GET,第二个操作 (GetVehicle()) 不响应,并且在设置时本身并用 [HttpGet] 错误装饰:

{
    "Message": "The requested resource does not support http method 'GET'."
}

此控制器似乎与上面的产品控制器相同:

public class VehiclesController : ApiController
{
    Vehicle[] vehicles = new Vehicle[]
    {
        new Vehicle { Code = 1, Type = "type1", BumperID = "H0002" },
        new Vehicle { Code = 2, Type = "type2", BumperID = "T0016" }
    };

    public IEnumerable<Vehicle> GetAllVehicles()
    {
        Console.WriteLine("GetAllVehicles()");
        return vehicles;
    }

    public IHttpActionResult GetVehicle(int code)
    {
        Console.WriteLine("GetVehicle() code = " + code);
        var vehicle = vehicles.FirstOrDefault((v) => v.Code == code);
        if (vehicle == null)
        {
            return NotFound();
        }

        return Ok(vehicle);
    }
}

但只有第一个动作被调用。我错过了什么?与单独的 SecurityController 完全相同的问题。 .NET 很新.....

添加了自托管路线图:

    public void Configuration(IAppBuilder app)
    {
        // Configure Web API for self-host. 
        var config = new HttpConfiguration();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        app.UseWebApi(config);
    }

有了上面的代码,

http://localhost:8080/api/vehicles

有效,但是

http://localhost:8080/api/vehicles/1

没有。

任何通过搜索到达这里的人 Jeffrey Rennie 的回答都是正确的 - {id} 中的 id 是字面意思。

【问题讨论】:

  • 能否给我们您的路线图
  • 编辑了我的帖子并添加了映射。

标签: c# asp.net


【解决方案1】:

尝试将GetVehicle() 的参数从code 重命名为id。这与 Anthony Liriano 的回答有关。默认路由模式需要一个名为 id 的参数。

【讨论】:

  • Kaboom - 我没有意识到配置中 {id} 中的 id 是字面意思。谢谢 - 只要允许我这样做,就会标记为答案。 .NET 的新手...
【解决方案2】:

您缺少路线和动词属性。这要求您使用 System.Web.Http 库。您可以在Attribute Routing in ASP.NET Web API 2 找到更多信息

[HttpGet, Route("api/your/route/here")]
public IHttpActionResult GetVehicle(int code)
{
    Console.WriteLine("GetVehicle() code = " + code);
    var vehicle = vehicles.FirstOrDefault((v) => v.Code == code);
    if (vehicle == null)
    {
        return NotFound();
    }

    return Ok(vehicle);
}

【讨论】:

  • 我试过了 - 它没有任何效果,并且在简单教程中没有使用这种方式,尽管我稍后会在端口中使用这条路线。 @Jeffrey Rennie 在下面是正确的并解决了这个问题。
【解决方案3】:

或者像这样装饰你的 api 端点

   [HttpGet("{code}/GetVehicleById")]
   public IHttpActionResult GetVehicle(int code)
    {
        Console.WriteLine("GetVehicle() code = " + code);
        var vehicle = vehicles.FirstOrDefault((v) => v.Code == code);
        if (vehicle == null)
        {
            return NotFound();
        }

        return Ok(vehicle);
    }

那时您的 api 端点调用将是

api/vehicles/123/GetVehicleById

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    • 2019-12-16
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    相关资源
    最近更新 更多