ControllerContext为null

Adm*_*eur 3 c# asp.net-mvc asp.net-mvc-4

我有这个MVC4控制器(ControllerB):

public class MyControllerB : Controller
{
    public bool Check(string actionName, ControllerBase controllerBase)
    {
        ControllerContext controllerContext = new ControllerContext(this.ControllerContext.RequestContext, controllerBase);

        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我从"ControllerA"调用ControllerB的Check方法,如下所示:

bool b = new MyControllerB().Check("Index", this);
Run Code Online (Sandbox Code Playgroud)

我知道Object reference not set to an instance of an object因为this.ControllerContext是null.

如果我将Check方法移动到ControllerA,它可以正常工作.但我需要这种方法在不同的控制器中.如何修复我的代码,以便``this.ControllerContext`不会为空?

Rau*_*ess 5

ControllerContext由于您是ControllerB从中手动创建实例,因此为null ControllerA.

通常,IController实例是由注册的IControllerFactory,通常创建的System.Web.Mvc.DefaultControllerFactory.控制器工厂将new()实例并正确初始化设置.

正如@DZL所说,让两个控制器子类化一个BaseController类通常要好得多,这个类可以具有共享初始化和共享属性和方法.

我不了解你要做的事情的业务逻辑,但这里是使用2个控制器的基类的代码示例:

namespace MyNamespace.Controllers
{
    public class MyControllerBase : Controller
    {
        public bool Check(string actionName, ControllerBase controllerBase)
        {
            ControllerContext controllerContext = new ControllerContext(this.ControllerContext.RequestContext, controllerBase);
            return false;
        }
    }
    public class MyControllerA : MyControllerBase
    {
        ActionResult Index()
        {
            bool b = base.Check("Index", this);
            return View();
        }
    }
    public class MyControllerB : MyControllerBase
    {
        ActionResult Index()
        {
            bool b = base.Check("Index", this);
            return View();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你真的想要完全按照你的要求去做,你就必须打电话IControllerFactory.CreateController(requestContext, controllerName)而不是new ControllerB(),但这是一种非常复杂的做事方式 - 我不推荐它.