ASP.NET5 MVC6 利用Middleware 建立可訪問HttpContext 的業務類工廠。(代替HttpContext.Current)

咱們的目標是在後臺業務處理類中,可以很容易的取得用戶信息或者其它HTTP請求相關的信息。cookie

因此,首先咱們須要一個存儲這些信息的類:app

1     public class RequestData
2     {
3         public string UserName { get; set; }
4 
5         public int UserId { get; set; }
6 
7         public UriBuilder Url { get; set; }
8     }

這個請求信息類,是咱們業務工廠類的一個屬性:async

 1     public class DataControllerFactory
 2     {
 3         public RequestData RequestData { get; set; } = new RequestData();
 4 
 5         public T Create<T>() where T : BaseBusiness
 6         {
 7             T dc = Activator.CreateInstance<T>();
 8             dc.RequestData = this.RequestData;
 9             return dc;
10         }
11     }

這個工廠類裏的BaseBusiness就是全部業務處理類的基類:ide

1     public class BaseBusiness
2     {
3         public RequestData RequestData { get; set; }
4     }

也許基類加上 abstract關鍵字更好些。  接着建立一個用於測試的業務處理類:測試

1 public class TestDataController: BaseDataController
2     {
3     }

好吧,它是空的,可是作測試夠用了。   後臺業務層就是上面這些類了。  下面是前臺MVC裏利用 DI 和 Middleware 實現RequestData的傳遞和業務類的建立。ui

首先建立RequestMiddlewarethis

 1     public abstract class AbstractMiddleware
 2     {
 3         protected RequestDelegate Next { get; set; }
 4 
 5         protected AbstractMiddleware(RequestDelegate next)
 6         {
 7             this.Next = next;
 8         }
 9 
10         public abstract Task Invoke(HttpContext context);
11     }
12 
13     public class RequestMiddleware:AbstractMiddleware
14     {
15         public RequestMiddleware(RequestDelegate next) : base(next) { }
16 
17         public async override Task Invoke(HttpContext context)
18         {
19             DataControllerFactory factory = context.RequestServices.GetService(typeof(DataControllerFactory)) as DataControllerFactory; 
20             factory.RequestData.UserName =  context.User.Identity.Name??"Not Login"; 
21             await this.Next.Invoke(context);
22         }
23     }

這裏用了個基類 AbstractMiddleware, 不過看來做用不大,它不是必須的。spa

在Startup類裏的 Configure 方法中, 註冊這個中間件:code

 app.UseMiddleware<RequestMiddleware>();

//下面的代碼也在Configure方法中,用於開啓cookie認證功能,這樣能夠大大的簡化登陸代碼,便於測試或者集成已有的用戶管理系統。
//app.UseIdentity();
            app.UseCookieAuthentication(options =>
            {
                options.AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.AutomaticAuthenticate = true;
                options.AutomaticChallenge = true;
                options.CookieHttpOnly = true;
            });

順便在其 ConfigureServices 方法中添加 業務類工廠 的依賴注入類型中間件

services.AddScoped<DataControllerFactory>();

有可能 這行代碼 須要在 services.AddMvc(); 的上面, 總之有時順序很重要, 但我尚未時間仔細測試這些問題。

下面咱們就要測試一下咱們能不能取得業務類工廠,而且建立出帶有登陸請求信息的業務類。

有了上面開啓cookie認證的代碼,咱們在Controller中的登陸Action便很簡單了:

 1         //這裏用了API形式的測試登陸方法 
       public string Login() 2 { 3 List<Claim> claims = new List<Claim>(); 4 claims.Add(new Claim("Name", "TestName", ClaimValueTypes.String)); 5 claims.Add(new Claim(ClaimTypes.Name, "TestName", ClaimValueTypes.String)); 6 ClaimsIdentity identity = new ClaimsIdentity(claims, "AuthenticationType", "Name", ClaimTypes.Role); 7 ClaimsPrincipal principal = new ClaimsPrincipal(identity); 8 HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal); 9 return "ok"; 10 }

下面是測試 Factory 和 相關登陸請求數據的 Action :

1         public IActionResult TestLogin()
2         {
3             var factor = GetService<DataControllerFactory>();
4             TestDataController tdc = factor.Create<TestDataController>();
5             ViewBag.UserName = tdc.RequestData.UserName;
6             return View();
7         }

VIEW層調用登陸action和測試action的方法很簡單,這裏就再也不寫了。

相關文章
相關標籤/搜索