咱們的目標是在後臺業務處理類中,可以很容易的取得用戶信息或者其它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的方法很簡單,這裏就再也不寫了。