2

我一直在关注http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api并在创建以下控制器后,我得到意想不到的结果...

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 Product GetProductById(int id)
    {
        var product = products.FirstOrDefault((p) => p.Id == id);
        if (product == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        return product;
    }
}

我希望能够拨打这样的电话:

/api/products/GetAllProducts

但这不起作用。相反,我可以简单地调用:

/api/产品

它实际上执行GetAllProducts(). 为什么这不能按预期工作?

4

2 回答 2

3

因为在 WebApi 框架中,它假设您需要“Get”方法。

你熟悉不同的http动词吗?发布、获取、放置、删除?当您在浏览器中输入 url 时,它会发出 Get 请求。框架看到了这一点,并假设您想要 GetAllProducts。

如果您有一个 DeleteAllProducts,并向它发出删除请求,/api/products它将运行该请求。

如果您有一个GetProduct(int id)并发出一个 Get 请求(例如,通过在浏览器地址栏中输入),api/products/1它将执行GetProcuct(1).

认为更像是一个基于 CRUD 的控制器。您可以只使用名为 Get、Post、Put、Delete 的操作,它会根据使用的 http 动词运行这些操作。想要更新产品?类似于public ActionResult Post(int id, [FromBody]Product p),您可以通过对 /api/products/1 的 POST 请求调用它。当然,需要在请求正文中发送 Product Json/XML 才能使序列化工作。

于 2013-08-29T17:06:52.997 回答
1

使用Url:/api/products/GetAllProducts它不起作用,因为您的 Web Api 仅支持默认路由:

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

为了使其按您的期望工作,您需要action在顶部添加一条支持的路线:

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

至于第二个URL: /api/products,它的工作原理是:

id默认路由是可选的 ( ) RouteParameter.Optional

并从链接

框架只选择与请求的 HTTP 方法(GET、POST、PUT、DELETE)匹配的操作,确定如下:

  • 具有属性的 HTTP 方法:AcceptVerbs、HttpDelete、HttpGet、HttpHead、HttpOptions、HttpPatch、HttpPost 或 HttpPut。

  • 否则,如果控制器方法的名称以“Get”、“Post”、“Put”、“Delete”、“Head”、“Options”或“Patch”开头,则按照惯例,该操作支持该 HTTP 方法。

  • 如果以上都不是,则该方法支持 POST。

在你的情况下,如果你从浏览器发出请求,它应该是一个 GET 请求,所以这个请求将映射到以Get(方法GetAllProducts)开头的动作

于 2013-08-29T17:13:17.313 回答