Khaine775
Khaine775

Reputation: 2765

ASP MVC ControllerFactory failing on AccountController

I'm using Unity and even though I shouldn't have to register my controllers (as far as I'm aware), I get the following error on my AccountController, which is just the one taken from the default MVC template when making a new project.

The IControllerFactory 'WebApplication1.Models.ControllerFactory' did not return a controller for the name 'Account'.

Stack trace:

[InvalidOperationException: The IControllerFactory 'WebApplication1.Models.ControllerFactory' did not return a controller for the name 'Account'.]
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +336
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +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& completedSynchronously) +155

The ControllerFactory looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Practices.Unity;

namespace WebApplication1.Models
{
public class ControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        try
        {
            if (controllerType == null)
            {
                throw new ArgumentNullException("controllerType");
            }
            if (!typeof(IController).IsAssignableFrom(controllerType))
            {
                throw new ArgumentException(string.Format("Type requested is not a controller: {0}", controllerType.Name), "controllerType");
            }
            return MvcUnityContainer.Container.Resolve(controllerType) as IController; //This is where it fails
        }
        catch (Exception e)
        {
            return null;

        }
    }
}

public static class MvcUnityContainer
{
    public static UnityContainer Container { get; set; }
}
}

The caught exception gives me this:

e = {"Resolution of the dependency failed, type = \"WebApplication1.Controllers.AccountController\", name = \"(none)\".\r\nException occurred while: while resolving.\r\nException is: InvalidOperationException - The current type, Microsoft.AspNet.Identity.IUserS...

I have no idea where to go from here, and any help is appreciated.

UPDATE:

AccountController class:

[Authorize]
public class AccountController : Controller
{
    private ApplicationSignInManager _signInManager;
    private ApplicationUserManager _userManager;

    public AccountController()
    {
    }

    public AccountController(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;
        }
    }

    //
    // GET: /Account/Login
    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }
}

UPDATE 2:

As suggested by Steven, I've removed the try-catch from the factory and get this exception:

An exception of type 'Microsoft.Practices.Unity.ResolutionFailedException' occurred in Microsoft.Practices.Unity.dll but was not handled in user code

Additional information: Resolution of the dependency failed, type = "WebApplication1.Controllers.AccountController", name = "(none)".

Exception occurred while: while resolving.

Exception is: InvalidOperationException - The current type, Microsoft.AspNet.Identity.IUserStore`1[WebApplication1.Models.ApplicationUser], is an interface and cannot be constructed. Are you missing a type mapping?

-----------------------------------------------

At the time of the exception, the container was:



  Resolving WebApplication1.Controllers.AccountController,(none)

  Resolving parameter "userManager" of constructor WebApplication1.Controllers.AccountController(WebApplication1.ApplicationUserManager userManager, WebApplication1.ApplicationSignInManager signInManager)

    Resolving WebApplication1.ApplicationUserManager,(none)

    Resolving parameter "store" of constructor WebApplication1.ApplicationUserManager(Microsoft.AspNet.Identity.IUserStore`1[[WebApplication1.Models.ApplicationUser, WebApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] store)

      Resolving Microsoft.AspNet.Identity.IUserStore`1[WebApplication1.Models.ApplicationUser],(none)

Upvotes: 1

Views: 1433

Answers (3)

tkc8800
tkc8800

Reputation: 11

I ran into this problem after installing Unity.MVC. I was getting errors logging in/out of the site. Turns out the controller constructors have to be separated between the Unity parameters and the identity parameters like so:

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

public AccountController(IUserRepository _repUser, IConfigRepository _repConfig)
{
    repUser = _repUser;
    repConfig = _repConfig;
}

Upvotes: 1

Khaine775
Khaine775

Reputation: 2765

I've fixed the error by adding the following two lines to the BuildUnityContainer() methods in the Bootstrapper.

container.RegisterType<AccountController>(new InjectionConstructor());
container.RegisterType<ManageController>(new InjectionConstructor());

Upvotes: 1

Steven
Steven

Reputation: 172626

Remove the try-catch statement from your custom ControllerFactory.GetControllerInstance and you will immediately see what the problem is. You can strip that method down to:

protected override IController GetControllerInstance(RequestContext requestContext, 
    Type controllerType)
{
    return (IController)MvcUnityContainer.Container.Resolve(controllerType);
}

Upvotes: 0

Related Questions