c#:从http请求报文看http协议中参数传递的几种方式

环境:

  • vs2019 16.5.1
  • asp.net core 3.1.1
  • Postman v7.14.0

一、在url中传递数据

这种方式适用于get/post方法,也是一种最简单、最直观的参数传递方式,不过由于过于直观(数据显示在浏览器地址栏中),不建议使用此种方式传递敏感数据(传递中文的时候要在javascript端进行编码 encodeURIComponent)。
http请求示例:

GET http://localhost:5000/Test/TestUrlPara?name=%E5%B0%8F%E6%98%8E&age=20 HTTP/1.1
User-Agent: PostmanRuntime/7.21.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 8f8c5745-1bd6-43da-8118-595b91fdb102
Host: localhost:5000
Accept-Encoding: gzip, deflate
Connection: keep-alive

上面传递的数据为:name=小明,age=20
后台接受方式:
webapi和webmvc相同

[HttpGet]
[HttpPost]
 public string TestUrlPara([FromQuery]string name, [FromQuery]int? age)
 {
     return $"hello:{name},你{age?.ToString()}岁了!";
 }

说明:[FromQuery]加不加都可以。

二、application/x-www-form-urlencoded

这是在post请求体里面的一种编码方式,要求http请求头中:Content-Type: application/x-www-form-urlencoded,直接看http请求示例:
http请求示例:

POST http://localhost:5000/Test/TestPostFormUrlencoded HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: PostmanRuntime/7.21.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 96f83832-4878-4b16-b4e7-f152f8a6fc47
Host: localhost:5000
Accept-Encoding: gzip, deflate
Content-Length: 30
Connection: keep-alive

name=%E5%B0%8F%E6%98%8E&age=20

上面传递的数据:name=小明,age=20
后台接受方式:
webapi:

[HttpPost]
public string TestPostFormUrlencoded([FromForm]string name, [FromForm]int? age)
{
   	return $"hello {name},你{age}岁了!";
}

注意:必须写上[FromForm],否则获取数据是null
webmvc
相比webapi,可以把[FromForm]去掉。

三、form-data

这是在post请求体里面的一种编码方式,要求http请求头中:Content-Type: multipart/form-data; boundary=xxxxxxxxxxx,这种方式可以上传文件,下面直接看http请求示例
http请求示例:

POST http://localhost:5000/Test/TestPostFormData HTTP/1.1
Content-Type: multipart/form-data; boundary=--------------------------004374744169603298126403
User-Agent: PostmanRuntime/7.21.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 11083367-0fec-4938-9464-47e430f07281
Host: localhost:5000
Accept-Encoding: gzip, deflate
Content-Length: 442
Connection: keep-alive

----------------------------004374744169603298126403
Content-Disposition: form-data; name="name"

小明
----------------------------004374744169603298126403
Content-Disposition: form-data; name="age"

20
----------------------------004374744169603298126403
Content-Disposition: form-data; name=""; filename="testupload.db"
Content-Type: application/octet-stream

xiaoming
----------------------------004374744169603298126403--

上面请求传递参数:name=小明,age=20,上传了一个文件testupload.db
后台接受方式:
application/x-www-form-urlencoded方式,webapi和webmvc的异同点也是一样的。

四、application/json

这是在post请求体里面的一种编码方式,要求http请求头中:Content-Type: application/json,直接看http请求示例:
http请求示例:

POST http://localhost:5000/Test/TestBodyJson HTTP/1.1
Content-Type: application/json
User-Agent: PostmanRuntime/7.21.0
Accept: */*
Cache-Control: no-cache
Postman-Token: bf664225-a214-4584-b5e2-8bead284d450
Host: localhost:5000
Accept-Encoding: gzip, deflate
Content-Length: 25
Connection: keep-alive

{"name":"小明","id":20}

后台接受方式:
webapi

[ApiController]
[Route("[controller]/[action]")]
 public class TestController : ControllerBase
 {
     [HttpPost]
     public string TestBodyJson([FromBody]User user)
     {
         if (user == null) return "user is null.";
         return Newtonsoft.Json.JsonConvert.SerializeObject(user);
     }

 }
 public class User
 {
     public string name { get; set; }
     public int? id { get; set; }
 }

web-mvc:方式同webapi

五、总结

我们知道,在http协议报文里传递的数据一般(也有很多在请求头里传递数据的,比如:jwt)都是放在url(get/post)里或者是请求体里(post)。

放在url里传递参数最简单、最直观,但是安全性较低,还有传递中文的时候要在javascript进行一个编码(encodeURIComponent("小明"))。

放在http请求体的参数一般要在http的请求头里表明请求体的数据格式(比如:Content-type:application/json表示请求体里面是json字符串),当然你也可以不标明请求体的数据合适,不过你就得自己解析里面的数据了。我们以asp.net core 3.1.1做为后台服务器,对这几种的编码方式做了测试,均能正常解析到参数值。

另外,我从postman中发现http的请求体里的编码方式还有很多,如下图所示:
在这里插入图片描述
上面我标注出来的,都是我没有测试的,估计aspnetcore框架本身也不支持,不过只要你愿意可以自己做个中间件支持一下~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章