路由和数据传递(02)

目录:

  • 路由规则

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"能访问, 且参数必须是序列化后的字符串

原文地址:https://www.cnblogs.com/shishixiang/p/13993875.html