2017-10-06 61 views
0

說實話,我不明白基於asp.net-core的web應用程序是如何工作的。現在我正試圖一點一點地弄清楚它是如何在幕後工作的。爲什麼我們必須爲每個操作方法調用await _userManager.GetUserAsync(User)?

讓我們考慮選擇Individual User Account的默認模板。更確切地說,在ManageController類中如下所示。

namespace StackOverflow.Controllers 
{ 
    [Authorize] 
    [Route("[controller]/[action]")] 
    public class ManageController : Controller 
    { 
     // others are trimmed for the sake of simplicity 

     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public async Task<IActionResult> EnableAuthenticator(EnableAuthenticatorViewModel model) 
     { 
      // .......... 

      var user = await _userManager.GetUserAsync(User); 
      // ........ 
     } 

     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public async Task<IActionResult> ResetAuthenticator() 
     { 
      var user = await _userManager.GetUserAsync(User); 
      //....... 
     } 

     [HttpGet] 
     public async Task<IActionResult> GenerateRecoveryCodes() 
     { 
      var user = await _userManager.GetUserAsync(User); 
      // .......... 
     }   
} 

問題

聲明

var user = await _userManager.GetUserAsync(User); 

幾乎每個動作方法時發生。

爲什麼我們必須調用await _userManager.GetUserAsync(User)每個操作方法?爲什麼我們不把它作爲一個類的財產?

回答

2

爲了使用類屬性,您需要一個異步屬性。這在C#中是不可能的 - 斯蒂芬·克萊瑞在這個主題here上進行了大量的細節。

這是一個有意義的設計決策,因爲「異步屬性」是一個矛盾。屬性獲取器應返回當前值;他們不應該開展後臺操作。另外,「異步setter」背後的語義並不完全清楚。

雖然你可能塊上的異步代碼,它不建議。 Stephen Cleary還有另一篇文章here

但是,你不應該。因爲當你阻止異步代碼時,你首先放棄了異步代碼的所有好處。只要阻塞線程,異步處理程序的增強可伸縮性就會失效。

+1

除了異步問題,還有其他原因嗎?在我的思維模型中,一個asp.net web應用程序在許多用戶之間共享,因此用戶請求對應於一個操作方法調用,因此,全局定義的用戶沒有意義。這是對的嗎? –

+1

'用戶'分配到'GetUserAsync'是控制器的一個屬性 - 對於每個單獨的請求,都有一個控制器的新實例,因此它有自己的'User'。如果'GetUser'作爲同步操作是一個選項,您可以根據需要使用屬性來包裝該呼叫。 –

+2

是的,一個HTTP請求通常映射到控制器的* new *實例上的一個'ActionMethod'調用。存儲在控制器級別的任何「全局」狀態將在請求之間丟失。因此,當你*可以*存儲它時,將它作爲局部變量存儲在'ActionMethod'中是沒有好處的。 –

相關問題