目录:
- 路由规则
1.Web Api有两种路由规则
- config.MapHttpAttributeRoutes(); 特性路由
- config.Routes.MapHttpRoutes(); 默认路由
注意:特性优先级大于默认
2.默认路由的规则
- 默认路由也称为基于公约路由
- 模板:"api/{controller}/{id}"
- 可以定义多个路由,name值不一样,满足规则即可
注意:当WebApi收到Http请求时,会匹配相应路由模板,api是一个字面路径避免和MVC发生冲突,其他都是占位符
3.方法命名约定
- 为了找到控制器,Web Api将"Controller"添加到{controller}变量上。
- 为了找到动作,Web Api会遍历HTTP方法,比如Get、Post、Put和Delete开头的方法
- 路由模板的其他占位符变量会映射。比如{id}会映射到动作的参数
4.路由的变化
- 也可以通过用HttpGet、HttpPut、HttpPost或HttpDelete属性来设定HTTP方法。
public class ProductsController : ApiController
{
[HttpGet]
public Product FindProduct(id) {}
}
- 一个动作支持多个Http方法:AcceptVerbs属性,将方法列表作为参数。
public class ProductsController : ApiController
{
[AcceptVerbs("GET", "HEAD")]
public Product FindProduct(id) { }
}
5.特性路由
- 公约路由优势,定义在单独的地方,一致的应用所有的控制器。缺点:很难支持确切的URL模式,不能很好的扩展。
- 特性路由能很容易的为这个URL定义一个路由
[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }
- 启用属性路由,在配置期间需要调用MapHttpAttributeRoutes 。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes(); // 启用特性路由
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
- 可有多个参数、路由前缀,能通过一个[RoutePrefix]属性来设置一个公共的前缀、在方法特性上可以用一个波浪符号重写路由前缀,前缀可以包含参数
//设置公共前缀
[RoutePrefix("api/books")] public class BooksController : ApiController { // GET api/books [Route("")] public IEnumerable<Book> Get() { ... } // GET api/books/5 [Route("{id:int}")] public Book Get(int id) { ... } // POST api/books [Route("")] public HttpResponseMessage Post(Book book) { ... } }
//重写前缀
[RoutePrefix("api/books")] public class BooksController : ApiController { // GET /api/authors/1/books [Route("~/api/authors/{authorId:int}/books")] public IEnumerable<Book> GetByAuthor(int authorId) { ... } }
- 可选的URI参数和默认值
public class BooksController : ApiController
{
[Route("api/books/locale/{lcid=1033}")]
public IEnumerable<Book> GetBooksByLocale(int lcid) { ... }
}
- 其他场景
API版本控制 (被路由到不同控制器)、重载URI片段 ("1"是一个阶数,而"pending"被映射到集合) 、多个参数类型 ("1"是一个阶数,而"2013/06/16"被指定为一个日期。)
6.请求规则
- Get请求规则
1.基础类型参数
// 动作方法代码
[HttpGet]
public string GetAllChargingData(int id, string name)
{
return "ChargingData" + id;
}
// JS代码
$.ajax({
type: "get",
url: "http://localhost:27221/api/Charging/GetAllChargingData",
data: { id: 1, name: "Jim", bir: "1988-09-11"},
success: function (data, status) {
if (status == "success") {
$("#div_test").html(data);
}
}
});
2.对象作为参数
// 模型
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public int Age { get; set; }
}
//动作方法
[HttpGet]
public string Create([FromUri]Person model)
{
return "提交的数据:" + model.ID;
}
// JS代码
$.ajax({
type: "get",
url: "http://localhost:27221/api/Person/Create",
contentType: "application/json",
data: { Id: "1", Name: "Jim", Gender: "男",Age:20 },
success: function (data, status) {
if (status == "success") {
$("#div_test").html(data);
}
}
});
- 使用Get方式提交对象,必须在动作方法的参数上添加 [FromUri] 特性,否则接受不到数据
- Post请求规则
1. 基础类型参数
注意:post请求则是通过http的请求体中传过来的,WebApi的post请求也需要从http的请求体里面去取参数
单个值
// JS代码
$.ajax({
type: "post",
url: "http://localhost:27221/api/Charging/SaveData",
data: { "": "Jim" }, //它的机制是=value,没有key的概念
success: function (data, status) {}
});
// 动作方法
[HttpPost]
public bool SaveData([FromBody]string NAME)
{
return true;
}
多个值
// JS代码
$.ajax({
type: "post",
url: "http://localhost:27221/api/Charging/SaveData",
contentType: 'application/json',
data: JSON.stringify({ NAME: "Jim",DES:"备注" }),
success: function (data, status) {}
});
// 动作方法
[HttpPost]
public object SaveData(dynamic obj)
{
var strName = Convert.ToString(obj.NAME);
return strName;
}
2.实体作为参数
//动作方法
[HttpGet]
public string Create([FromBody]Person model)
{
return "提交的数据:" + model.ID;
}
// JS代码
$.ajax({
type: "post",
url: "http://localhost:27221/api/Person/Create",
data: { Id: "1", Name: "Jim", Gender: "男",Age:20 },
success: function (data, status) {
if (status == "success") {
$("#div_test").html(data);
}
}
});
3. 数组作为参数
// JS代码
var arr = ["1", "2", "3", "4"];
$.ajax({
type: "post",
url: "http://localhost:27221/api/Charging/SaveData",
contentType: 'application/json',
data: JSON.stringify(arr),
success: function (data, status) { }
});
// 动作方法
[HttpPost]
public bool SaveData(string[] ids)
{
return true;
}
实体集合作为参数
var arr = [
{ ID: "1", NAME: "Jim", CREATETIME: "1988-09-11" },
{ ID: "2", NAME: "Lilei", CREATETIME: "1990-12-11" },
{ ID: "3", NAME: "Lucy", CREATETIME: "1986-01-10" }
];
$.ajax({
type: "post",
url: "http://localhost:27221/api/Charging/SaveData",
contentType: 'application/json',
data: JSON.stringify(arr),
success: function (data, status) {}
});
[HttpPost]
public bool SaveData(List<Person> models)
{
return true;
}
总结:推荐用实体接收或用dynamic类型接收,用实体接收,无论是"application/x-www-form-urlencoded"还是"application/json"都能访问;如果用dynamic类型接收,只有"application/json"能访问, 且参数必须是序列化后的字符串