一次HTTP請求,就是一次標準IO操作,請求是I,是輸入;回應式O,是輸出,任何web開發框架,其實都是在干這兩件事:
- 接受請求并進行決議獲取引數
- 根據引數進行渲染并輸出回應內容
所以我們學習一個框架,我認為最首要的是知道如何從請求中獲取引數,http請求攜帶引數的地方主要有下面幾個地方:
- URL
- Header
- Body
下面看看ASP.NET Core是如何從這幾個位置獲取引數的,
通過URL獲取引數
通過URL傳參是HTTP最最常用的辦法,這里簡單介紹下URL相關的知識,一個URL主要分成4個部分,以http://localhost:5000/fromurl/test?name=mjzhou&age=10為例:
| http:// | 協議 |
| localhost:5000 | 主機地址 |
| /fromurl/test | PATH |
| name=mjzhou&age=10 | QueryString |
我們通常使用PATH跟QueryString來傳遞引數,新建一個MVC專案,新建一個Controller名為FromUrlController,通過幾個Action來演示如何從URL上獲取引數,
通過QuerySting獲取引數
Request.Query物件
// /fromurl/test?name=mjzhou
public IActionResult Test()
{
var name = Request.Query["name"];
return Content(name);
}
Request.Query物件包含了本次請求的QueryString的鍵值對串列,所以可以通過它輕松獲取QueryString上攜帶的引數,
自動引數系結
// /fromurl/test?name=mjzhou
public IActionResult Test1(string name)
{
return Content(name);
}
如果Action的型參的名稱跟QueryString的Key一致,則MVC框架會自動幫我們系結引數的值,不用手動獲取,
public IActionResult Test2([FromQuery(Name = "id")]string bh)
{
return Content(bh);
}
如果引數系結的名稱跟QueryString的Key不一致,可以使用FromQueryAttribute強制指定系結的Key的名稱,
通過PATH獲取引數
Request.Path物件
// /fromurl/test3
public IActionResult Test3()
{
var path = Request.Path;
return Content(path);
}
Request.Path物件包含了本次http請求的Path的原始資訊,一般可以通過/來分隔,手工獲取想要的引數,
自動引數系結
// /fromurl/Test4/mjzhou/1000
[Route("FromUrl/test4/{name}/{id}")]
public IActionResult Test4(string name, int id)
{
return Content($"{name}/{id}");
}
Path的自動引數系結,需要配合RouteAttribute實作,RouteAttribute主要是指定一個Path的模板,通過這個模板可以告訴路由是否匹配這個Action,另外一個就是可以告訴引數系結,如何決議這個path實作引數系結,
[Route("FromUrl/test6/{name}/{id}")]
public IActionResult Test6([FromRoute(Name ="name")]string xm, [FromRoute(Name = "id")]int bh)
{
return Content($"{xm}/{bh}");
}
如果Action的型參名稱跟RouteAttribute模板的中的名稱不一樣,那么可以使用FromRoute強制指定決議的名稱,
[HttpGet("FromUrl/test5/{name}/{id}")]
public IActionResult Test5(string name, int id)
{
return Content($"{name}/{id}");
}
HttpGetAttribute、HttpPostAttribute等attribute同樣可以完成RouteAttribute的效果,而且還指定了action接受的HTTP Method的方法,可以說是加強版的RouteAttribute,
從Header上獲取引數
添加一個FromHeaderController,通過幾個action來演示如果從http headers上獲取引數,
Request.Headers物件
// /FromHeader/test
public IActionResult Test()
{
var myName = Request.Headers["myName"];
return Content(myName);
}
Request.Headers是一個字典,包含了本次請求的Headers,所以我們可以通過Request.Headers物件輕松獲取某個header的值,
自動引數系結
public IActionResult Test1([FromHeader]string myName)
{
return Content(myName);
}
通過在action的型參上打上FromHeaderAttribute,可以告訴框架自動從header獲取引數,
public IActionResult Test2([FromHeader(Name = "myName")]string name)
{
return Content(name);
}
如果action的型參跟header的key值不一致,可以通過FromHeaderAttribute強制指定匹配的header的key值,
從Body獲取引數
我們開發的時候經常通過表單提交資料,或者通過AJAX往后臺提交一個JavaScript物件,本質上這些資料都是通過HTTP的Bady提交回去的,新建一個FromBodyController控制器,通過幾個Action來演示如何獲取Body的引數,
Request.Body物件
public class model1
{
public string NAME { get; set; }
}
public async Task<IActionResult> Test()
{
Request.EnableBuffering();
string body = "";
var stream = Request.Body;
if (stream != null)
{
stream.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(stream, Encoding.UTF8, true, 1024, true))
{
body = await reader.ReadToEndAsync();
}
stream.Seek(0, SeekOrigin.Begin);
}
var model = JsonConvert.DeserializeObject<model1>(body);
return Content(model.NAME);
}
Request.Body是一個Stream,保存了本次請求的body資料,所以我們只要把這個stream讀出來,就能獲取提交的資料,有了原始的資料,就可以通過反序列化等操作轉換為模型,更簡單的獲取引數了,注意,ASP.NET Core想要讀取這個物件,必須先呼叫Request.EnableBuffering()這個方法,
使用postman測驗一下:

引數自動系結
public IActionResult Test1([FromBody]model1 model)
{
return Content(model.NAME);
}
使用FromBodyAttribute可以把body的資料自動反序列化成型參的模型,但是請注意使用[FromBody]請求的Content-Type必須是application-json,
使用postman測驗下:


public IActionResult Test2([FromForm]model1 model)
{
return Content(model.NAME);
}
使用FromFormAttribute可以把body的資料自動反序列化成型參的模型,但是請注意使用[FromForm]請求的Content-Type必須是application/x-www-form-urlencoded,
使用postman測驗下:


總結
ASP.NET Core獲取請求引數主要從URL,Headers,Body等位置獲取,我們可以通過Request.Query、Request.Headers、Request.Body來手工獲取資料,也可以通過[FromQuery]、[FromHeader]、[Frombody]等Attribute來實作引數的自動系結,
關注我的公眾號一起玩轉技術

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/36128.html
標籤:.NET Core
