「傳導體」 HttpContexthtml
要理解 HttpContext 是幹嗎的,首先,看圖web
圖一 內網訪問程序api
圖二 反向代理訪問程序瀏覽器
ASP.NET Core 程序中,Kestrel 是一個基於 libuv 的跨平臺 ASP.NET Core web 服務器。不清楚 Kerstrel 不要緊,之後慢慢了解。服務器
咱們能夠理解成,外部訪問咱們的程序,經過 Http 或者 Https 訪問,例如 https://localhost:44337/Home/Index,須要經過一個網址,來尋向訪問特定的頁面。
訪問頁面時,會產生 Cookie、Seesion、提交表單、上傳數據、身份認證等,外部與應用程序之間傳導的導體就是 HttpContext。
websocket
總之,客戶端跟 Web應用程序交互 是經過 HttpContext 傳導的。cookie
原理
ASP.NET Core 本質是一個控制檯程序!ASP.NET Core 程序並不直接監聽請求,而是經過依賴 HTTP Server ,來實現把各自請求轉發到應用程序中。這個被轉發的請求至關於咱們平常瀏覽網頁、上傳文件、提交表單等的網絡請求,這些請求會被包裝,而後組合到 HttpContext 中。
就好像顧客到餐廳吃飯網絡
HttpContext 至關於這個服務員,她在前、後傳遞信息。session
操做 HttpContext 前期準備socket
通常來講,咱們主要寫好Web程序,而無需理會 數據是怎麼傳導的。就好像兩臺電腦可以發送資料,咱們用不着知道他們是經過無線Wifi、光纖仍是銅線電纜傳輸的。
當有須要時,天然須要用~ 廢話少說,先簡單操做 HttpContext 瞭解下。後面接着解析這個對象。
若是你不須要練習,請直接跳過這一節內容。
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); //先不用管這個是幹嗎的
public class HomeController : Controller { private IHttpContextAccessor _accessor; public HomeController(IHttpContextAccessor accessor) { _accessor = accessor; } [HttpGet] public IActionResult Index(int? id) { var httpcontext = _accessor.HttpContext; return View(httpcontext); } }
@model Microsoft.AspNetCore.Http.HttpContext @{ Layout = null; }
到這裏,準備已經完成。
以上代碼的做用是把 HttpContext 對象 傳遞到 視圖 中,直接在視圖中使用。這樣咱們在理解時,只需在視圖測試便可。
HttpContext 的屬性
在 ASP.NET Core 中,系統爲每個請求分配一個線程,HttpContext 針對的,就是一個線程。因此它的類、方法、屬性等,都是針對當前請求起做用。
Properties(特性)
Authentication | 這個已經用不到了,這裏只是列一下表。 用於身份認證(ASP.NET中用到),官方不建議在ASP.NT Core中使用。替代方案 Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions |
Connection | 獲取有關此請求的基礎鏈接的信息 |
Features | 獲取此請求上可用的服務器和中間件提供的HTTP特性的集合 |
Items | 獲取或設置可用於在該請求範圍內共享數據的鍵/值集合 |
Request | 請求 |
RequestAborted | 通知此請求基礎的鏈接什麼時候停止,所以請求操做應取消 |
RequestServices | 獲取或設置 IServiceProvider 集合,提供訪問的請求的服務容器 |
Response | 響應 |
Session | 獲取或設置用於管理此請求的用戶會話數據的對象 |
TraceIdentifier | 獲取或設置用於在跟蹤日誌中表示此請求的惟一標識符 |
User | 獲取或設置此請求的用戶 |
WebSockets | 獲取一個對象,該對象管理此請求的WebSu套鏈接的創建 |
下面介紹列表中特性的使用。
Request
用於獲取用戶請求的對象,瀏覽器向Web程序提交表單、訪問的URL、URL中包含的查詢字符串、報文請求頭等等。
Body | 獲取或設置 RequestBody 流 |
ContentLength | 獲取或設置 Content-Length 頭 |
ContentType | 獲取或設置Content-Type 頭 |
Cookies | 獲取或設置 Cookies |
Form | 獲取或設置 表單內容 |
HasFormContentType | Checks the Content-Type header for form types. |
Headers | Gets the request headers. |
Host | 獲取或設置主機頭。能夠包括端口 |
HttpContext | 獲取或設置請求上下文 |
IsHttps | 檢測當前是否HTTPS鏈接 |
Method | 獲取或設置HTTP方法 |
Path | 獲取或設置當前請求的路徑,即URL |
PathBase | 獲取或設置 RequestPathBase,就是URL前面那一段,如https://docs.microsoft.com |
Protocol | Gets or sets the RequestProtocol. |
Query | 查詢字符串的集合 |
QueryString | 獲取或設置用於在Request.Query中建立查詢集合的原始查詢字符串 |
Scheme | 獲取或設置HTTP請求方案 |
試一試
打開 Index.Cshtml ,把如下代碼加上去
(爲了看得清楚一點,我加了表格)
<table> <tr> <td>RequestBody流</td> <td> @Model.Request.Body</td> </tr> <tr> <td>Content-Length頭</td> <td>@Model.Request.ContentLength</td> </tr> <tr> <td>Content-Type頭</td> <td> @Model.Request.ContentType</td> <tr> <td>Cookies </td> <td>@Model.Request.Cookies</td> </tr> <tr> <td>IsHttps</td> <td>@Model.Request.IsHttps</td> </tr> <tr> <td>Host </td> <td>@Model.Request.Host</td> </tr> </table>
運行Web程序,結果以下
在瀏覽器 F12 後,能夠看到控制檯的內容。請查看 下圖的 一、3部分
Request 的其它使用方法,就再也不贅述,你能夠在視圖中 @Model.Request. 加上須要測試的屬性便可。
推薦別人關於 Request 的文章 https://www.cnblogs.com/Sea1ee/p/7240943.html
Response
Request 是 客戶端向 Web 發送請求,而 Response 則是 Web 響應 客戶端 的請求。這裏筆者就不所有翻譯了
使用Response能夠直接影響服務器響應,設置響應內容、響應類型(發送網頁、文件、圖片等)、視圖響應前重定向。
Response 應該在控制器中使用。具體使用方法筆者這裏就不贅述。
Body | 獲取或設置響應體流 |
ContentLength | Gets or sets the value for the |
ContentType | 獲取或設置內容類型響應標頭的值 |
Cookies | 獲取一個對象,該對象可用於管理此響應的Cookie |
HasStarted | Gets a value indicating whether response headers have been sent to the client. |
Headers | Gets the response headers. |
HttpContext | Gets the HttpContext for this response. |
StatusCode | Gets or sets the HTTP response code. |
注意:
使用Response.Headers屬性,往Http響應中添加Http Header的時候,不能添加劇複名字的Header,例以下面代碼中咱們添加了三個名爲"Header001"的Header到Response中,這樣會拋出異常:
Response.Headers.Add("Header001", "1000"); Response.Headers.Add("Header001", "1000"); Response.Headers.Add("Header001", "1000");正確的作法應該是,先用Response.Headers.Keys檢測將要添加的Header是否已經在Response中存在,若是已經存在就直接修改,而不是添加:
//使用Response.Headers.Keys檢測是否Response中已經存在"Header001" if (!Response.Headers.Keys.Contains("Header001")) { //若是不存在就添加"Header001" Response.Headers.Add("Header001", "1000"); } else { //若是存在就修改"Header001" Response.Headers["Header001"] = "1000"; }
Response 的方法
OnCompleted(Func<Task>) |
在響應已發送到客戶端以後添加要調用的委託 |
OnCompleted(Func<Object,Task>, Object) | 響應已發送到客戶端以後添加要調用的委託 |
OnStarting(Func<Task>) | 在響應頭將被髮送到客戶端以前添加要調用的委託 |
OnStarting(Func<Object,Task>, Object) | 在響應頭將被髮送到客戶端以前添加要調用的委託 |
Redirect(String) | 向客戶端返回一個臨時重定向響應(HTTP 302) |
Redirect(String, Boolean) | 向客戶端返回重定向響應(HTTP 301或HTTP 302) |
RegisterForDispose(IDisposable) | 處置(不可分)在請求完成處理後,註冊主機處理的對象 |
Response 拓展方法
GetTypedHeaders(HttpResponse) | |
WriteAsync(HttpResponse, String, Encoding, CancellationToken) | 取消令牌使用給定的編碼將給定文本寫入響應體 |
WriteAsync(HttpResponse, String, CancellationToken) | 將給定文本寫入響應體。UTF-8編碼將被使用 |
Clear(HttpResponse) | |
SendFileAsync(HttpResponse, IFileInfo, Int64, Nullable<Int64>, CancellationToken) | 使用Sendfile 擴展發送給定的文件 |
SendFileAsync(HttpResponse, IFileInfo, CancellationToken) | Sends the given file using the SendFile extension. |
SendFileAsync(HttpResponse, String, Int64, Nullable<Int64>, CancellationToken) | Sends the given file using the SendFile extension. |
SendFileAsync(HttpResponse, String, CancellationToken) | Sends the given file using the SendFile extension. |
請參考下圖的第 2 部分
Item
若是你使用過 ViewData,就不難理解 HttpContext.Item
HttpContext.Item 是一個字典集合類型,具體類型爲 IDictionary<TModel,TModel>。它的使用方法像 ViewData。(不要跟我說你不知道 ViewBag、ViewData 是什麼~)
打開 Index.Cshtml ,用下面代碼複製替換
@model Microsoft.AspNetCore.Http.HttpContext @{ Layout = null; } @{ List<string> i = new List<string>(); i.Add("a"); i.Add("b"); i.Add("c"); i.Add("d"); i.Add("e"); i.Add("f"); i.Add("g"); i.Add("h"); i.Add("i"); Model.Items["Test"] = i; /* Model.Items 是字典類型 這裏設置 鍵 Test 值 i ,它的值是 List<string> 類型 */ foreach(var item in Model.Items["Test"] as List<string>) //字典類型,必須先用 as 轉爲對應類型 { <br> @item } }
結果
能夠用 HttpContext.Item 來存儲當前請求的意向有用的數據。
HttpContext 的其它方法使用這裏再也不贅述,須要注意的是,HttpContext 是針對一個請求的而產生的。