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

Posted

技术标签:

【中文标题】在控制器的构造函数中访问 HttpContext.Request【英文标题】:accessing HttpContext.Request in a controller's constructor 【发布时间】:2010-08-08 01:01:27 【问题描述】:

我正在关注这个ASP.NET MVC tutorial from Microsoft:

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

namespace SCE.Controllers.Application

    public abstract class ApplicationController : Controller
    
        public ApplicationController()
        
            bool usuario = HttpContext.Request.IsAuthenticated;
                   
    

问题是HttpContext 始终为空。

有解决办法吗?

【问题讨论】:

Null ControllerContext in my custom controller inheriting from BaseController的可能重复 【参考方案1】:

与其将HttpContext.Request.IsAuthenticated 放在控制器级别,不如将其放在控制器基类中,该类将在所有控制器中通过 OnActionExecuting() 方法的覆盖方法继承。

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

public class BaseController : Controller

    protected override void OnActionExecuting(ActionExecutingContext ctx) 
        base.OnActionExecuting(ctx);
        ViewData["IsAuthenticated"] = HttpContext.Request.IsAuthenticated;
    

你所有的 Controller 都应该继承 BaseController 类

public class ApplicationController : BaseController

现在您应该在母版页中获得ViewData["IsAuthenticated"]

编辑

通过您提供的链接以及与您所做的相关,您的ApplicationController 是页面控制器,而不是基本控制器。在示例中,ApplicationController 是由 HomeController 继承的基本控制器,但您所做的是将 Action 方法放在基本控制器中,即 ApplicationController,因此您的 Action Index 方法将不会被调用当您调用任何不是来自 ApplicationController 的页面(索引页面)时。

【讨论】:

我不得不将 Public 更改为 Protected 以使其在我的代码中工作,因为错误:在覆盖“受保护”继承成员时无法更改访问修饰符 我想你会想覆盖OnActionExecuting,它发生在Action代码运行之前,而不是OnActionExecuted,它发生在之后——所以你可以访问ViewData(或其他)在您的方法中 您似乎覆盖了OnActionExecuting,但在实现中调用了base.OnActionExecuted。这对我来说似乎是一个错字。 哦,是的.. 不错。我已将覆盖的方法更改为OnActionExecuting 而不是OnActionExecuted,并且该部分没有更改。谢谢 应该OnActionExecuting(ActionExecutedContext ctx)OnActionExecuting(ActionExecutingContext ctx) 吗?【参考方案2】:

我建议你使用:

 System.Web.HttpContext.Current.Request

请记住 System.Web.HttpContext.Current 是线程静态的,但如果您不使用额外的线程,则该解决方案有效。

【讨论】:

我相信这篇文章是正确的答案,其余的取决于最佳实践、个人喜好和手头的任务。 我想知道为什么Controller.HttpContext没有使用这个实现 对我来说是个问题。将控制器的 httpContext 属性误认为是 HttpContext.Current【参考方案3】:

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

【讨论】:

只有 DI 就地控制器构造函数包含代码,通常它只是一行 _repository = repository【参考方案4】:

这个问题的解决方法是通过传递RequestContext对象创建一个Initialize的override方法。

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;
        
    

【讨论】:

【参考方案5】:

有了我在这里发布的答案,您无法访问 IsAuthenticated,但您可以访问一些与 HttpContextRequest 相关的内容(见图),

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

您可以如下使用 IHttpContextAccessor:

public ABCController(IHttpContextAccessor httpContextAccessor)   

     //do you stuff with httpContextAccessor,  

     // This gives session value
     string abc = httpContextAccessor.HttpContext.Session.GetString("Abc");

而在startup.cs中,需要进行配置,

services.AddHttpContextAccessor();

【讨论】:

以上是关于在控制器的构造函数中访问 HttpContext.Request的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core 中获取没有构造函数注入的注入服务的实例?

net abp core的appservice中访问httpcontext对象

将 HttpContext 注入到一个类中,并在 .net core 中调用控制器外的类

用于单元测试 .NET 核心 MVC 控制器的模拟 HttpContext?

如何在asp.net core中获取当前用户

ASP.NET Core 访问控制器构造函数中的 User.Identity