在控制器的构造函数中访问HttpContext.Request

ozs*_*gal 52 asp.net-mvc controllers httpcontext

我正在关注Microsoft的这个ASP.NET MVC教程:

我的代码略有不同,我试图HttpContext.Request.IsAuthenticated在控制器的构造函数中访问.

namespace SCE.Controllers.Application
{
    public abstract class ApplicationController : Controller
    {
        public ApplicationController()
        {
            bool usuario = HttpContext.Request.IsAuthenticated;
        }           
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是HttpContext始终为空.

这个问题有方法解决吗?

rob*_*nal 105

HttpContext.Request.IsAuthenticated您应该将它放在Controller Base类中,而不是将您置于Controller级别,该类将使用OnActionExecuting()方法的覆盖方法在所有控制器中继承.

在你的控制器基础上你应该有

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext ctx) {
        base.OnActionExecuting(ctx);
        ViewData["IsAuthenticated"] = HttpContext.Request.IsAuthenticated;
    }
}
Run Code Online (Sandbox Code Playgroud)

并且所有Controller都应该继承BaseController类

public class ApplicationController : BaseController
Run Code Online (Sandbox Code Playgroud)

现在你应该进入ViewData["IsAuthenticated"]你的母版页面.

编辑

通过您提供的链接以及与您所做的相关的链接,您ApplicationController就是一个页​​面控制器,而不是一个基本控制器.在示例中,ApplicationController是一个继承的基本控制器,HomeController但是您所做的是将Action方法放在基本控制器中,ApplicationController这样就可以在调用任何页面时调用Action Index方法(索引页面)那不是来自ApplicationController.

  • 我必须将`Public`更改为`Protected`以使其在我的代码中工作,因为错误:_在覆盖'protected'继承的member_时不能更改访问修饰符 (3认同)
  • 你好像在重写`OnActionExecuting`但在实现中调用`base.OnActionExecuted`.这看起来像是一个错字. (2认同)

Ghi*_*nio 51

我建议你使用:

 System.Web.HttpContext.Current.Request
Run Code Online (Sandbox Code Playgroud)

只记得System.Web.HttpContext.Current是threadstatic,但如果你不使用额外的线程,解决方案的工作原理.

  • 我相信这篇文章是正确答案,其余的都是最佳实践,个人喜好和手头的任务. (6认同)
  • 我想知道为什么`Controller.HttpContext`没有使用它来实现 (2认同)

spe*_*der 9

Controller在调用Index操作之前显着实例化,并且在构造时HttpContext确实不可用.在控制器方法中引用它有什么问题Index

  • 只有DI就位控制器构造函数包含代码,通常它只是一行_repository = repository (6认同)

小智 8

此问题的解决方案是通过传递RequestContext对象来创建Initialize的覆盖方法.

public class ChartsController : Controller
{
     bool isAuthed = false;
    protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {
        base.Initialize(requestContext);

        if (requestContext.HttpContext.User.Identity.IsAuthenticated)
        {
          isAuthed =true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

在此输入图像描述根据我在这里发布的答案,您无法访问 IsAuthenticated,但您可以访问与 HttpContextRequest 相关的一些内容(参见图片),

我需要构造函数中的会话值。

您可以按如下方式使用 IHttpContextAccessor:

public ABCController(IHttpContextAccessor httpContextAccessor)   
{
     //do you stuff with httpContextAccessor,  

     // This gives session value
     string abc = httpContextAccessor.HttpContext.Session.GetString("Abc");
}
Run Code Online (Sandbox Code Playgroud)

在startup.cs中,您需要配置,

services.AddHttpContextAccessor();
Run Code Online (Sandbox Code Playgroud)


fay*_*r78 5

可以使用注入到类构造函数中的IHttpContextAccessor来获取HttpContext 。在此之前,您需要首先在Startup.cs类或Program.cs中将相应的服务注册到服务容器,如下所示。

services.AddHttpContextAccessor(); // Startup.cs

builder.Services.AddHttpContextAccessor(); // Program.cs
Run Code Online (Sandbox Code Playgroud)

之后,您可以在任何方法或类构造函数中注入 IHttpContextAccessor 接口。

 private bool isAuthenticated { get; set; }

    public ConstructorName(IHttpContextAccessor accessor)
    {
        var context = accessor.HttpContext;

        isAuthenticated = context.User.Identity.IsAuthenticated;
    }
Run Code Online (Sandbox Code Playgroud)