从一个控制器调用方法到另一个控制器时,Session为null ... MVC

时间:2021-09-27 21:06:46

I have an ASP.NET MVC app and i added a new controller to it and call a method from this new controller from an existing controller. I am using session variables and in controller A i call the method in controller B:

我有一个ASP.NET MVC应用程序,我添加了一个新的控制器,并从现有控制器调用这个新控制器的方法。我正在使用会话变量,在控制器A中我调用控制器B中的方法:

if (Session["Grid"] != null){}//session object is fine here
      ControllerB b  = new ControllerB ();
b.CallMethod();

In the new controller, which i'm calling B, the method looks like this:

在新控制器中,我正在调用B,方法如下所示:

public object CallMethod(){
    if (Session["Grid"] != null)//session object is null
        {
            //do my thing
        }
  }

The session variable isnt the problem, its the session object. Its completely null, hence my application blows up. The session is alive and well in controller A, so why is it null in controller B? Thank you

会话变量不是问题,它是会话对象。它完全无效,因此我的应用程序爆炸了。会话在控制器A中运行良好,那么为什么在控制器B中它为空?谢谢

3 个解决方案

#1


12  

That's because ControllerB needs to initializes itself, and as part of this process it also sets Session, Request, Resposne etc accordingly.

这是因为ControllerB需要自己初始化,并且作为此过程的一部分,它还相应地设置Session,Request,Resposne等。

So, you need to call the Initialize method and pass it the current RequestContext. But, since it's marked as protected (because it wasn't meant to be called directly, only using the ControllerFactory), you'll have to expose it:

因此,您需要调用Initialize方法并将其传递给当前的RequestContext。但是,因为它被标记为受保护(因为它不是直接调用,只使用ControllerFactory),所以你必须公开它:

public class ControllerB : Controller
{
    public void InitializeController(RequestContext context)
    {
        base.Initialize(context);
    }
}

Then in your ControllerA:

然后在你的ControllerA中:

var controllerB = new ControllerB();
controllerB.InitializeController(this.Request.RequestContext);

Alternatively, since the Session getter is actually a shorthand for this.ControllerContext.HttpContext.Session (same for Request, Response etc), you can set the ControllerContext instead:

或者,由于Session getter实际上是this.ControllerContext.HttpContext.Session的简写(对于Request,Response等相同),您可以设置ControllerContext:

var controllerB = new ControllerB();
controllerB.ControllerContext = new ControllerContext(this.Request.RequestContext, controllerB);

See MSDN

#2


1  

This is happening because Session is a property that is initialized different based on how the controller is called.

发生这种情况是因为Session是根据控制器的调用方式而初始化的属性。

Instead of Session you can use HttpContext.Session. HttpContext refers to the current http request.

您可以使用HttpContext.Session而不是Session。 HttpContext引用当前的http请求。

public object CallMethod(){
    if (HttpContext.Session["Grid"] != null)//session object is null
    {
        //do my thing
    }
}

#3


1  

This is easily fixed through the good coding practice of "tell, don't ask", ie you pass the required value into the method, rather than expecting it to go looking for it for itself:

这可以通过“告诉,不要问”的良好编码实践轻松解决,即您将所需的值传递给方法,而不是期望它自己寻找它:

if (Session["Grid"] != null)
{
    var b  = new ControllerB ();
    b.CallMethod(Session["Grid"]);
}

...
public object CallMethod(string grid)
{
    //do your thing
}

#1


12  

That's because ControllerB needs to initializes itself, and as part of this process it also sets Session, Request, Resposne etc accordingly.

这是因为ControllerB需要自己初始化,并且作为此过程的一部分,它还相应地设置Session,Request,Resposne等。

So, you need to call the Initialize method and pass it the current RequestContext. But, since it's marked as protected (because it wasn't meant to be called directly, only using the ControllerFactory), you'll have to expose it:

因此,您需要调用Initialize方法并将其传递给当前的RequestContext。但是,因为它被标记为受保护(因为它不是直接调用,只使用ControllerFactory),所以你必须公开它:

public class ControllerB : Controller
{
    public void InitializeController(RequestContext context)
    {
        base.Initialize(context);
    }
}

Then in your ControllerA:

然后在你的ControllerA中:

var controllerB = new ControllerB();
controllerB.InitializeController(this.Request.RequestContext);

Alternatively, since the Session getter is actually a shorthand for this.ControllerContext.HttpContext.Session (same for Request, Response etc), you can set the ControllerContext instead:

或者,由于Session getter实际上是this.ControllerContext.HttpContext.Session的简写(对于Request,Response等相同),您可以设置ControllerContext:

var controllerB = new ControllerB();
controllerB.ControllerContext = new ControllerContext(this.Request.RequestContext, controllerB);

See MSDN

#2


1  

This is happening because Session is a property that is initialized different based on how the controller is called.

发生这种情况是因为Session是根据控制器的调用方式而初始化的属性。

Instead of Session you can use HttpContext.Session. HttpContext refers to the current http request.

您可以使用HttpContext.Session而不是Session。 HttpContext引用当前的http请求。

public object CallMethod(){
    if (HttpContext.Session["Grid"] != null)//session object is null
    {
        //do my thing
    }
}

#3


1  

This is easily fixed through the good coding practice of "tell, don't ask", ie you pass the required value into the method, rather than expecting it to go looking for it for itself:

这可以通过“告诉,不要问”的良好编码实践轻松解决,即您将所需的值传递给方法,而不是期望它自己寻找它:

if (Session["Grid"] != null)
{
    var b  = new ControllerB ();
    b.CallMethod(Session["Grid"]);
}

...
public object CallMethod(string grid)
{
    //do your thing
}