一. 基本调用规则
1. 前提
WebApi的默认路由规则为:routeTemplate: “api/{controller}/{id}”, 下面为我们统一将它改为 routeTemplate: “api/{controller}/{action}/{id}”,这样我们在调用的时候,还是通过拼接方法名来识别,不用考虑上面的坑别的规则了,这里我单纯的来探讨WebApi的传参和调用。
2. 基本的调用规则
是什么请求,在方法上面标注什么特性,常见的有[HttpGet]、[HttpPost]、[HttpPut]、[HttpDelete]。
PS:方法名以Get、Post、Put、Delete开头,WebApi会自动默认这个请求就是Get、Post、Put、Delete请求。
而如果你以其他名称开头而又不标注方法的请求方式,那么这个时候服务器虽然找到了这个方法,但是由于请求方式不确定,所以直接返回给你405——方法不被允许的错误。
二 参数传递小知识
1.HttpGet
我们可以自定义 [FromUri]实体类 或者 ([FromUri]实体类+单个/多个参数名) 来接收参数。 前端传过来的参数名是实体类中的各个参数名+单个/多个参数名,不需要是实体类的类名。
① 单个/多个参数名: OK
② 单个实体类: OK
③ 实体类+单个/多个参数名: OK
服务端代码:
public class TestClass
{
public string username { get; set; }
public string password { get; set; }
}
public class ValuesController : ApiController
{
//①单个/多个参数名 OK
//[HttpGet]
//public JsonResult<string> Get(string userName, string passWord)
//{
// if (userName == null && passWord == null)
// return Json("NG");
// return Json("OK");
//}
//② 单个实体类 OK
//[HttpGet]
//public JsonResult<string> Get([FromUri] TestClass testClass)
//{
// if (testClass == null)
// return Json("NG");
// return Json("OK");
//}
//③ 实体类+单个/多个参数名 OK
[HttpGet]
public JsonResult<string> Get([FromUri] TestClass testClass, string data)
{
if (testClass == null && data ==null)
return Json("NG");
return Json("OK");
}
}
2.HttpPost
我们可以自定义实体类或者[FromBody]实体类来接收参数。 前端传过来的参数名是实体类中的各个参数名,不需要是实体类的类名。
假若传递的参数类型的特性为[FromBody]时,需要注意:作为被标记为[FromBody]的参数只能出现一次,并且 [FromBody] 参数不能是基本的数据类型(如byte、int、bool、DateTime、string等)。
① 单个实体类: OK
② [FromBody]单个实体类: OK
③ [FromBody]实体类+单个/多个参数名: 找不到与请求 URI匹配的 HTTP 资源
④ 多个参数名: 找不到与请求 URI匹配的 HTTP 资源
服务端代码:
//① 单个实体类: OK
//[HttpPost]
//public JsonResult<string> Post(TestClass testClass)
//{
// if (testClass == null)
// return Json("NG");
// return Json("OK");
//}
//② [FromBody]单个实体类: OK
//[HttpPost]
//public JsonResult<string> Post([FromBody] TestClass testClass)
//{
// if (testClass == null)
// return Json("NG");
// return Json("OK");
//}
//③ [FromBody] 实体类+单个/多个参数名: 找不到与请求 URI匹配的 HTTP 资源
[HttpPost]
public JsonResult<string> Post([FromBody] TestClass testClass, string data)
{
if (testClass == null && data == null)
return Json("NG");
return Json("OK");
}
三 特殊情况
1. Post请求带Uri参数,服务端后台可以用多个参数名/[FromUri]实体类 接收
①Postman Params:
服务端可以接收到参数的值:
②FromUri接收参数:
Postman Params:
服务端可以接收到参数的值:
此处如果通过Request或者Request.QueryString相关方法可以获取请求值。Request.Form不能获取值。
由此可见 Post请求带Uri 和 Get请求Uri,服务端后台写法一样。
2. Post请求带Uri参数和Body参数。
服务端后台可以用[FromUri] 和[FromBody]接收参数
Postman Params:
3. Post请求带Uri参数和Body参数。
服务端后台可以用实体类 和单个/多个参数名接收参数
4. Post请求,前端以Params发送参数,后端带FromBody标识,则后端接收不到参数的值
Postman Params:
服务端代码:
5.Post请求带Uri参数和Body参数。Uri参数名(userName)和Body参数名(userName)同名时,Request中的userName等于哪个的值:
①Postman Params:
②Postman Body:
可以看出 Ruquest中的userName等于Request.QueryString中参数值。
四. 总结
Put和Delete请求与Post请求的规则相同,另外还有很多极端的情况,不探讨了,掌握正确的用法,直接去用最佳用法即可。
总结:记住Get请求和Post请求的标准用法以及基本的调用规则,其他坑爹的情况,可以统统忘记了,注意的是ajax的Get请求,加上一个当前时间或者随机数的参数,使用HttpClient 等需要禁用缓存。