ApplicationUserManager& ApplicationSignInManager在basecontrollererrors中

时间:2016-09-04 07:54:57

标签: c# asp.net asp.net-mvc asp.net-mvc-5 ninject.web.mvc

您好我试图移动ApplicationUserManager& ApplicationSignInManager到基本控制器,所以我在每个班级都有它。

但现在我收到了这个错误:

  

[InvalidOperationException:尝试创建时出错   'Site.Controllers.HomeController'类型的控制器。确保这一点   控制器有一个无参数的公共构造函数。]

下面的完整堆栈跟踪。

在我的BaseController中我有这个:

[Authorize]
public class BaseController : Controller
{
    protected ApplicationSignInManager _signInManager;
    protected ApplicationUserManager _userManager;

    protected IUnitOfWork UnitOfWork { get; set; }
    protected ApplicationUser _CurrentUser;

    public BaseController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
    {
           UserManager = userManager;
           SignInManager = signInManager;
    }

    public ApplicationSignInManager SignInManager
    {
        get
        {
            return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
        }
        private set
        {
            _signInManager = value;
        }
    }

    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

    protected IAuthenticationManager AuthenticationManager
    {
        get
        {
            return HttpContext.GetOwinContext().Authentication;
        }
    }
}

HomeController我有这个:

public class HomeController : BaseController
{
    public HomeController(IUnitOfWork UnitOfWork)
    {
        this.UnitOfWork = UnitOfWork;
    }

    public ActionResult Index()
    {
        return View("Index");
    }
}

在我的Startup.Auth我有这个:

namespace Site.App_Start
{
    public partial class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {

            app.CreatePerOwinContext(MoonDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                ExpireTimeSpan = TimeSpan.FromMinutes(10),
                LoginPath = new PathString("/Login"),
                Provider = new CookieAuthenticationProvider
                {

                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });

        }
    }
}

这是我得到的错误:

  

[InvalidOperationException:尝试创建时出错   'Site.Controllers.HomeController'类型的控制器。确保这一点   控制器有一个无参数的公共构造函数。]
  System.Web.Mvc.DefaultControllerActivator.Create(的RequestContext   requestContext,Type controllerType)+178
  System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(的RequestContext   requestContext,Type controllerType)+76
  System.Web.Mvc.DefaultControllerFactory.CreateController(的RequestContext   requestContext,String controllerName)+88
  System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase   httpContext,IController&amp;控制器,IControllerFactory&amp;厂)   +191 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext,AsyncCallback回调,对象状态)+50
  System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext,   AsyncCallback回调,对象状态)+48
  System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext的   context,AsyncCallback cb,Object extraData)+16
  System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()   +103 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+155

我只想稍微清理我的代码并将管理器移到基类,好像我错过了一步

2 个答案:

答案 0 :(得分:1)

我会进行一些设计更改,以使基本控制器更清洁一些。你的控制器应该依赖于抽象而不是结核。

首先将基本控制器的依赖项移动到更简单的抽象中。

public interface IApplicationManager {
    ApplicationSignInManager SignInManager { get; }
    ApplicationUserManager UserManager { get; }
}

您创建实现以在其中创建管理器。

然后对您的基本控制器进行重构:

[Authorize]
public class BaseController : Controller {
    protected ApplicationSignInManager _signInManager;
    protected ApplicationUserManager _userManager;

    protected IUnitOfWork UnitOfWork { get; set; }
    protected ApplicationUser _CurrentUser;

    public BaseController(IApplicationManager appManager) {
        UserManager = appManager.UserManager;
        SignInManager = appManager.SignInManager;
    }

    public ApplicationSignInManager SignInManager {
        get {
            return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
        }
        private set {
            _signInManager = value;
        }
    }

    public ApplicationUserManager UserManager {
        get {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set {
            _userManager = value;
        }
    }

    protected IAuthenticationManager AuthenticationManager {
        get {
            return HttpContext.GetOwinContext().Authentication;
        }
    }
}

在构造函数中使用参数创建基本控制器的问题是从它继承的类需要确保也调用该基本构造函数。鉴于您正在使用DI,那么您需要确保必要的依赖项也传递给死亡类。

public class HomeController : BaseController {
    public HomeController(IUnitOfWork UnitOfWork, IApplicationManager appManager)
        : base(appManager) {
        this.UnitOfWork = UnitOfWork;
    }

    public ActionResult Index() {
        return View("Index");
    }
} 

最后确保依赖项解析程序(IDependencyResolver)了解如何解析IApplicationManager到其实现,ApplicationSignInManagerApplicationUserManager否则您将获得相同的结果无参数构造函数错误。您使用Ninject标记了问题,因此您应该开始查看,因为您只设置了OWIN DI。

答案 1 :(得分:0)

您的BaseController没有无参数构造函数。执行HomeController : BaseController时,您要求使用BaseController的无参数构造函数。

要解决此问题,您需要BaseController中的另一个构造函数来设置参数,或者您需要执行HomeController : BaseController(p1, p2)(现在不在Visual Studio前面,因此可能不是100%正确的代码,只是从记忆中做到了)