2017-03-24 117 views
0

我在使用HttpContext類時遇到了問題。 我可以訪問HttpContext,但不能調用它的函數。你如何使用'HttpContext'類?

我想在我寫的幫助器類中使用HttpContext.Authentication。

我不能幫助我的類裏寫這樣的事(見下文):

private void SignInUser() 
{ 
... Code 
await HttpContext.Authentication.SignInAsync(..); 
} 

不過,我可以訪問我的HttpContext控制器類裏面。

我很感激任何幫助。提前致謝。

+2

可能重複的[Access HttpContext.Current](http://stackoverflow.com/questions/31243068/access-httpcontext-current) – DavidG

+0

您是否正在嘗試訪問用戶身份? – trevorc

+0

@trevorc我特別試圖在幫助類中使用SignInAsync方法。 – tocoolforscool

回答

2

首先創建文件HttpContext.cs

using Microsoft.AspNetCore.Builder; 
using Microsoft.AspNetCore.Http; 
using Microsoft.Extensions.DependencyInjection; 

namespace System.Web 
{ 
    public static class HttpContext 
    { 
     private static IHttpContextAccessor _contextAccessor; 

     public static Microsoft.AspNetCore.Http.HttpContext Current => _contextAccessor.HttpContext; 

     internal static void Configure(IHttpContextAccessor contextAccessor) 
     { 
      _contextAccessor = contextAccessor; 
     } 
    } 

    public static class StaticHttpContextExtensions 
    { 
     public static void AddHttpContextAccessor(this IServiceCollection services) 
     { 
      services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 
     } 

     public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app) 
     { 
      var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>(); 
      System.Web.HttpContext.Configure(httpContextAccessor); 
      return app; 
     } 
    } 
} 

接下來在你的啓動文件

public void ConfigureServices(IServiceCollection services) 
... 
services.AddTransient<IHttpContextAccessor, HttpContextAccessor>(); 
services.AddHttpContextAccessor(); 
... 

最後例如從控制器的,如果你需要當前用戶名

var currentUsername = !string.IsNullOrEmpty(System.Web.HttpContext.Current?.User?.Identity?.Name) 
      ? System.Web.HttpContext.Current.User.Identity.Name 
      : "Anonymous"; 

我經過測試的惠特ASPNET Core 1.0和1.1

編輯 對不起,我忘了在部分配置你的啓動文件補充一點:如果你wannt使用一個輔助類,它在用戶的跡象,你應該做一個擴展方法來代替,這無論是環繞

public void Configure(IApplicationBuilder app) 
... 
app.UseStaticHttpContext(); 
... 
+0

好吧真棒我即將實現這一點。如果我要寫一個圖書館來實現這個目標呢?我問,因爲庫中沒有啓動文件。我明白,你可以明顯地在庫中使用的核心應用程序中配置啓動文件,但如果我不希望我的用戶必須執行任何配置,該怎麼辦?或者這是值得的,它是自己獨立的問答? – tocoolforscool

+1

有關HttpContext的更多信息,請參閱http://www.strathweb.com/2016/12/accessing-httpcontext-outside-of-framework-components-in-asp-net-core/](http://www。 strathweb.com/2016/12/accessing-httpcontext-outside-of-framework-components-in-asp-net-core/) –

+0

很好的回答和參考。謝謝。 – tocoolforscool

1

IHttpContextAccessorHttpContext本身。

public static class HttpContextExtensions 
{ 
    public static void SignInUser(this HttpContext context) 
    { 
     await context.Authentication.SignInAsync(..); 
    } 

    public static void SignInUser(this.IHttpContextAccessor contextAccessor) 
    { 
     // Calls the method from above 
     contextAccessor.HttpContext.SignInUser(); 
    } 
} 

或者,如果你有一個更大的依存關係鏈,並要求其他注射服務,將其轉換成可注射類:

public class UserLogonService : IUserLogonService 
{ 
    private readonly IHttpContextAccessor contextAccessor; 

    public UserLogonService(IHttpContextAccessor contextAccessor) 
    { 
     if(contextAccessor==null) 
      throw new ArgumentNullException(nameof(contextAccessor)); 

     this.contextAccessor = contextAccessor; 
    } 

    public void SingInUser() 
    { 
     contextAccessor.HttpContext.SignInUser(); 
    } 
} 

Startup.Configure方法:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 
services.AddSingleton<IUserLogonService, UserLogonService>(); 

現在你可以在項目中通過構造函數無處不在注入IUserLogonService,即

public class MyController 
{ 
    private readonly IUserLogonService userLogon; 

    public MyController(IUserLoggonService userLogon) 
    { 
     this.userLogon = userLogon; 
    } 

    public async Task<IActionResult> Login() 
    { 
     await userLogon.SignInUser(); 
    } 
} 

它乾淨,解耦,可以很容易地進行單元測試,這是靜態幫助器類無法做到的。