在控制器外部使用HttpContext

时间:2017-03-11 05:24:29

标签: c# asp.net-core-mvc httpcontext

public class UserAccount
{
  private readonly IHttpContextAccessor _httpContextAccessor;

  public UserAccount(IHttpContextAccessor httpContextAccessor)
  {
    _httpContextAccessor = httpContextAccessor;
  }

  //Sign in
  public static async Task SignIn(dynamic user)
  {
    var claims = new[]
    {
      new Claim("UserID", user.ID.ToString()),
      new Claim(ClaimTypes.Role, "Baller")
    };

    var principal = new ClaimsPrincipal(
          new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme));

    await _httpContextAccessor.HttpContext.Authentication.SignInAsync("Cookies", principal);
  }
}

我从SignIn方法中的await语句中收到此错误:非静态字段,方法或属性“UserAccount._httpContextAccessor”

需要对象引用

如果我没有将方法声明为静态,则错误消失,但是如果方法未声明为静态,则无法从我的控制器访问方法UserAccount.SignIn。

如果我将变量 _httpContextAccessor 声明为:

private static IHttpContextAccessor

而不是:

private readonly IHttpContextAccessor

所有错误都消失了,但我再次在await语句中得到一个空引用异常。 (_httpContextAccessor未设置为对象的实例)

4 个答案:

答案 0 :(得分:6)

我认为您打算查看当前 HttpContext。为此,您需要为控制器构造函数添加IHttpContextAccessor的依赖项,然后在操作方法中使用该接口的HttpContext属性来访问当前上下文。

您可能需要注册

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

在您的Startup.cs中,具体取决于您是否已经由其他可能依赖它的常用服务添加此服务。

答案 1 :(得分:2)

  

我收到此错误

您无法从静态成员访问实例成员。您可能需要阅读static members

  

如果我没有将方法声明为静态

,则错误消失

是的,因为实例方法可以访问实例字段。

  

然而,从我的控制器,如果方法IS未声明为静态,我无法访问UserAccount.SignIn方法。

当然可以 - 但他们需要实例

private UserAccount _userAccount;
ControllerConstructor(IHttpContextAccessor accessor)
{
  _userAccount = new UserAccount(accessor);
}

...
// Inside an action method:
await _userAccount.SignIn(user);
  

如果我声明变量_httpContextAccessor [as static],所有错误都会消失

是的,因为静态方法可以访问静态字段。

  

但我再次在await语句中得到一个空引用异常。

因为静态字段从未初始化。

答案 2 :(得分:0)

我的解决方案:

在启动中注册HttpContextAccessor

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

然后获取当前用户:

using (var scope = host.Services.CreateScope())
{
    var currentContext = scope.GetService<IHttpContextAccessor>();
    return currentContext.HttpContext.User;
}

答案 3 :(得分:-1)

您可以像这样访问HttpContext:

@if (Context.User.Identity.IsAuthenticated)
{
    <ul class="nav navbar-nav navbar-right">
        <li>
            <a asp-area="" asp-controller="User" asp-action="Logout">Logout</a>
        </li>
    </ul>
}
else
{
    <ul class="nav navbar-nav navbar-right">
        <li><a asp-area="" asp-controller="User" asp-action="Register">Register</a></li>
        <li><a asp-area="" asp-controller="User" asp-action="Login">Log in</a></li>
    </ul>
}

不需要任何指令或包。