ASP.NET Core 中 HttpContext 詳解與使用 | Microsoft.AspNetCore.Http 詳解
筆者沒有學 ASP.NET ,直接學 ASP.NET Core ,學完 ASP.NET Core MVC 基礎後,開始學習 ASP.NET Core 的執行原理。發現應用程式有一個非常主要的 “傳導體” HttpContext 。
趕忙寫一下筆記先。
“傳導體” HttpContext
要理解 HttpContext 是幹嘛的,首先,看圖
圖一 內網訪問程式
圖二 反向代理訪問程式
ASP.NET Core程式中, Kestrel 是一個基於 libuv 的跨平臺 ASP.NET Core web 伺服器。不清楚 Kerstrel 沒關係,以後慢慢了解。
我們可以理解成,外部訪問我們的程式,通過 Http 或者 Https 訪問,例如 https://localhost:44337/Home/Index ,需要通過一個網址,來尋向訪問特定的頁面。
訪問頁面時,會產生 Cookie、Seesion、提交表單、上傳資料、身份認證等,外部與應用程式之間傳導的導體就是 HttpContext 。
總之,客戶端跟 Web應用程式互動 是通過 HttpContext 傳導的。
操作 HttpContext 前期準備
一般來說,我們主要寫好Web程式,而無需理會 資料是怎麼傳導的。就好像兩臺電腦能夠傳送資料,我們用不著知道他們是通過無線Wifi、光纖還是銅線電纜傳輸的。
當有需要時,自然需要用~ 廢話少說,先簡單操作 HttpContext 瞭解下。後面接著解析這個物件。
如果你不需要練習,請直接跳過這一節內容。
- 開啟 VS(2017)
- 新建專案
- ASP.NET Core Web 應用程式
- Web應用程式(模型檢視控制器)
- 開啟 Startup.cs ,在 ConfigureServices 中,加上
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); //先不用管這個是幹嘛的
- 開啟 HomeController.cs ,在頂部 using Microsoft.AspNetCore.Http; 把 HomeController 類替換成以下程式碼
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); } }
-
開啟 Views/Home 目錄,刪除除 Index.cshtml 外的其它檢視
- 把 Index.cshtml 的程式碼改成
@model Microsoft.AspNetCore.Http.HttpContext @{ Layout = null; }
到這裡,準備已經完成。
以上程式碼的作用是把 HttpContext 物件 傳遞到 檢視 中,直接在檢視中使用。這樣我們在理解時,只需在檢視測試即可。
HttpContext 的屬性
在 ASP.NET Core 中,系統為每一個請求分配一個執行緒,HttpContext 針對的,就是一個執行緒。所以它的類、方法、屬性等,都是針對當前請求起作用。
Properties(特性)
ofollow,noindex" target="_blank">Authentication | 這個已經用不到了,這裡只是列一下表。 用於身份認證(ASP.NET中用到),官方不建議在ASP.NT Core中使用。替代方案 Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions |
Connection | 獲取有關此請求的基礎連線的資訊 |
Features | 獲取此請求上可用的伺服器和中介軟體提供的HTTP特性的集合 |
Items | 獲取或設定可用於在該請求範圍內共享資料的鍵/值集合 |
Request | 請求 |
RequestAborted | 通知此請求基礎的連線何時中止,因此請求操作應取消 |
RequestServices | 獲取或設定 IServiceProvider 集合,提供訪問的請求的服務容器 |
Response | 響應 |
Session | 獲取或設定用於管理此請求的使用者會話資料的物件 |
TraceIdentifier | 獲取或設定用於在跟蹤日誌中表示此請求的唯一識別符號 |
User | 獲取或設定此請求的使用者 |
Sockets" rel="nofollow,noindex" target="_blank">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 後,可以看到控制檯的內容。請檢視 下圖的 1、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 的方法
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 是針對一個請求的而產生的。