C# MVC4WebAPI中的操作
我一直在跟踪,在创建了以下控制器之后,我得到了意想不到的结果C# MVC4WebAPI中的操作,c#,asp.net-mvc-4,asp.net-web-api,C#,Asp.net Mvc 4,Asp.net 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, Na
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;
}
}
公共类产品控制器:ApiController
{
产品[]产品=新产品[]
{
新产品{Id=1,Name=“番茄汤”,Category=“杂货”,Price=1},
新产品{Id=2,Name=“Yo”,Category=“Toys”,Price=375万},
新产品{Id=3,Name=“Hammer”,Category=“Hardware”,Price=16.99M}
};
公共IEnumerable GetAllProducts()
{
退货产品;
}
公共产品GetProductById(int id)
{
var product=products.FirstOrDefault((p)=>p.Id==Id);
如果(产品==null)
{
抛出新的HttpResponseException(HttpStatusCode.NotFound);
}
退货产品;
}
}
我希望能够打这样的电话:
/api/产品/GetAllProducts
但这是行不通的。相反,我可以简单地称之为:
/原料药/产品
这实际上执行了
GetAllProducts()
中描述的过程。为什么这不能像预期的那样工作?因为在WebApi框架中,它假设您需要“Get”方法
您熟悉不同的http动词吗?发布、获取、放置、删除?在浏览器中键入url时,会发出Get请求。框架看到了这一点,并假设您想要获取所有产品
如果您有一个DeleteAllProducts,并向/api/products
发出了删除请求,它将运行该请求
如果您有一个GetProduct(int-id)
并向api/products/1
发出一个Get请求(例如,通过在浏览器地址栏中键入),它将执行GetProduct(1)
将is更多地看作是一个基于CRUD的控制器。您可以只使用名为Get、Post、Put、Delete的操作,它将根据所使用的http谓词运行这些操作。想要更新产品吗?它类似于
public ActionResult Post(intid,[FromBody]Product p)
,您可以通过对/api/products/1的Post请求调用它。当然,产品Json/XML需要在请求体中发送,以便序列化工作。因为在WebApi框架中,它假设您需要“Get”方法
您熟悉不同的http动词吗?发布、获取、放置、删除?在浏览器中键入url时,会发出Get请求。框架看到了这一点,并假设您想要获取所有产品
如果您有一个DeleteAllProducts,并向/api/products
发出了删除请求,它将运行该请求
如果您有一个GetProduct(int-id)
并向api/products/1
发出一个Get请求(例如,通过在浏览器地址栏中键入),它将执行GetProduct(1)
将is更多地看作是一个基于CRUD的控制器。您可以只使用名为Get、Post、Put、Delete的操作,它将根据所使用的http谓词运行这些操作。想要更新产品吗?它类似于
public ActionResult Post(intid,[FromBody]Product p)
,您可以通过对/api/products/1的Post请求调用它。当然,产品Json/XML需要在请求正文中发送,才能进行序列化。使用Url
:/api/products/GetAllProducts
它不起作用,因为您的web api只支持默认路由:
configuration.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
为了让它按照您的期望工作,您需要再添加一条路线来支持顶部的操作
:
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
)使用Url
:/api/products/GetAllProducts
它不起作用,因为您的web api只支持默认路由:
configuration.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
为了让它按照您的期望工作,您需要再添加一条路线来支持顶部的操作
:
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
)这里的详细信息:谢谢,@Alex我正在寻找类似的内容来添加。这里的详细信息:谢谢,@Alex我在找类似的东西来补充。