.NET Core技術研究-HttpContext訪問的正確姿勢


  將ASP.NET升級到ASP.NET Core之后,相信大家都會遇到HttpContext.Current無法使用的問題。這也是我們遷移ASP.NET Core必須解決的問題。

  本文我們詳細討論一下,使用HttpContext的正確姿勢。

  先列一下使用HttpContext的具體場景:

1. 在Controller層訪問HttpContext

2. 在中間件中使用HttpContext

3. 在數據訪問層使用HttpContext

4. 在后台線程中訪問HttpContext

5. 在Razor頁面模型中訪問HttpContext

6. 在Razor視圖中訪問HttpContext

  可能還有其他的應用場景。接下來我們按場景一一示例解決。

  首先本文用的是ASP.NET Core 3.1

  一、新建一個ASP.NET Core Web應用程序

  

  

  

  

二、在Controller層訪問HttpContext

   示例代碼中HomeController繼承與Controller抽象類

   Controller父類中繼承與ControllerBase抽象類

   其中ControllerBase抽象類有提供了對HttpContext的訪問

  

  所以,我們在Controller這一層可以按以下方式訪問HttpContext:

復制代碼
 1  public class HomeController : Controller  2  {  3 private readonly ILogger<HomeController> _logger;  4 private string customer;  5  6 public HomeController(ILogger<HomeController> logger)  7  {  8 _logger = logger;  9 10  customer = HttpContext.Request.Form["CustomerId"]; 11  } 12 }
復制代碼

 三、在中間件中使用HttpContext

    自定義擴展中間件中,實現Invoke方法,HttpContext通過參數的方式傳遞到中間件的業務邏輯中。

 public async Task Invoke(HttpContext context)
復制代碼
 1 public class CustomerMiddleware  2 {  3 private readonly RequestDelegate _next;  4  5 public CustomerMiddleware(RequestDelegate next)  6  {  7 _next = next;  8  }  9 10 public async Task Invoke(HttpContext context) 11  { 12 // Do something with context near the beginning of request processing. 13 await _next.Invoke(context); 14 15 // Clean up. 16  } 17 }
復制代碼

四. 在數據訪問層使用HttpContext

 聲明一個User的倉儲類,實現對User的持久化。如下代碼中,

UserRepository依賴 IHttpContextAccessor 

通過ASP.NET Core依賴注入容器解析依賴鏈並創建 UserRepository 實例時,就會注入依賴項。

復制代碼
 1  public class UserRepository: IUserRepository  2  {  3 private readonly IHttpContextAccessor _httpContextAccessor;  4  5 public UserRepository(IHttpContextAccessor httpContextAccessor)  6  {  7 _httpContextAccessor = httpContextAccessor;  8  }  9 10 public void AddUser(User user) 11  { 12 var username = _httpContextAccessor.HttpContext.User.Identity.Name; 13 14 //Save User to DB 15  } 16 }
復制代碼

 使用ASP.NET Core內置的依賴項注入容器來注冊依賴項。 依賴項注入容器向任意類提供 IHttpContextAccessor,以供類在自己的構造函數中將它聲明為依賴項:

復制代碼
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews();  services.AddHttpContextAccessor(); services.AddTransient<IUserRepository, UserRepository>(); }
復制代碼

 五、在后台線程中訪問HttpContext

 HttpContext 不是線程安全的。 在處理請求之外讀取或寫入 HttpContext 的屬性,可能會導致 NullReferenceException空引用異常。

 如何再后台線程中使用HttpContext呢?推薦的做法:

  1. 在請求處理過程中復制所需的數據。

  2. 將復制的數據傳遞給后台任務。

  

  六、在Razor頁面模型中訪問HttpContext

  Razor頁面模型的父類PageModel提供了HttpContext的訪問,如下代碼:

復制代碼
1  public class UserModel: PageModel 2 { 3 public string Message { get; set; } 4 5 public void OnGet() 6  { 7 Message = HttpContext.Request.PathBase; 8  } 9 }
復制代碼

 七、 在Razor視圖中訪問HttpContext

   Razor 視圖通過視圖上的 RazorPage.Context 屬性直接公開 HttpContext

@{
    ViewData["Title"] = "Home Page"; var username = Context.User.Identity.Name; }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM