【问题标题】:ASP.NET MVC 4 + Ninject MVC 3 = No parameterless constructor defined for this objectASP.NET MVC 4 + Ninject MVC 3 = 没有为此对象定义无参数构造函数
【发布时间】:2012-08-31 22:42:31
【问题描述】:

更新 - 请查看我的答案以获取此问题的解决方案的链接和说明

在我们开始之前,我知道这是一个非常常见的问题,我已经使用 Ninject 很多个月都没有问题,但现在它出现了,我无法找到解决办法。另外,不,到目前为止,Google 和 SO 上的结果都没有帮助我。

因此,考虑在 Windows Server 2008 R2 上的 Visual Studio 2012 的一个非常、非常、非常简单的原型 ASP.NET MVC 4 项目上运行的以下代码:

public class DefaultController : Controller {
    private IGroupPrincipalRepository GroupPrincipalRepository { get; set; }

    [Inject]
    public DefaultController(
        IGroupPrincipalRepository groupPrincipalRepository) {
        this.GroupPrincipalRepository = groupPrincipalRepository;
    }
}

这是NinjectWebCommon.cs RegisterServices 方法:

kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor(
    c =>
        new GroupPrincipalRepository(new PrincipalContext(ContextType.Domain, "?", "?", "?", "?"))).InSingletonScope();

现在,这就是我使用 Ninject 的其他项目(但在 .NET 4 上是 ASP.NET MVC 3)的工作方式,据我所知,这是使一切正常工作所需要的。那么,为什么我突然得到 No parameterless constructor defined for this object. 异常?

更新

这是完整的NinjectWebCommon.cs 文件:

[assembly: WebActivator.PreApplicationStartMethod(typeof(App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(App_Start.NinjectWebCommon), "Stop")]

namespace App_Start {
    using System;
    using System.DirectoryServices.AccountManagement;
    using System.Repositories.ActiveDirectory;
    using System.Web;
    using Microsoft.Web.Infrastructure.DynamicModuleHelper;
    using Ninject;
    using Ninject.Web.Common;

    public static class NinjectWebCommon {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        public static void Start() {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        public static void Stop() {
            bootstrapper.ShutDown();
        }

        private static IKernel CreateKernel() {
            var kernel = new StandardKernel();
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            RegisterServices(kernel);
            return kernel;
        }

        private static void RegisterServices(
            IKernel kernel) {
            kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor(
                c =>
                    new GroupPrincipalRepository(new PrincipalContext(ContextType.Domain, "", "", "", ""))).InSingletonScope();
        }
    }
}

更新 - 请查看我的答案以获取此问题的解决方案的链接和说明

【问题讨论】:

  • 您在哪里创建 DependecyResolver 并覆盖默认值?
  • 我认为这就是 NinjectWebCommon.cs 文件正在做的事情,如果不是,那么我猜答案是“不知道在哪里”。再说一次,我很困惑,因为我的其他项目都是这样工作的,我已经进行了两次和三次检查以确保我没有撒谎......
  • 在 Ninject.MVC 包中有一个 NinjectMvcHttpApplicationPlugin 负责处理 DependecyResolver... 所以它应该可以工作吗?你如何安装 Ninject.MVC ?使用 Nuget?
  • 是的,使用 NuGet,最新版本然后我更改 NinjectWebCommon.cs 文件,正如 Git 中心文档所说。我刚刚用一个新的 MVC 4 项目尝试了另一个测试,在一个注入的单个控制器中只有一个 ActionResult。仍然因同样的问题而失败。
  • 我尝试在我的本地计算机上使用 Visual Studio 2010、MVC 4、.NET 4 进行另一项测试,这次错误没有发生。我将假设罪魁祸首是 VS2012 或 .NET 4.5。以 .NET 4.0 为目标并不能解决问题。

标签: c# asp.net-mvc asp.net-mvc-4 ninject visual-studio-2012


【解决方案1】:

嗯,我没有确切的答案为什么会出现错误,但我知道 导致它,那就是 Visual Studio 2012。我在与 2012 年相同的机器上安装了 Visual Studio 2010,为 2010 年安装了 ASP.NET MVC 4,我将 2012 年的项目重新创建为 2010 年逐字逐句、逐字逐句。最终结果是,当 2010 调试项目时,一切正常,Ninject 注入了应有的依赖项。

当 2012 调试它的项目时,它只是出现了 No parameterless constructor defined for this object 异常。 2012 年 .NET 4.0 和 .NET 4.5 之间的重新定位没有任何作用。从 NuGet 重新安装 Ninject 也无济于事。我什至将 2010 年和 2012 年的项目都配置为使用本地 IIS 服务器,以确保完全确定,最终结果是相同的。

我将假设 Visual Studio 2012 或 Ninject 存在错误。我在这两个项目之间的唯一区别是它们运行的​​是哪个 IDE,而 2012 项目是崩溃的那个,所以这就是我将矛头指向 Visual Studio 2012 的原因。

更新

伙计们。伙计们!我又遇到了这个问题,并在另一个 SO 问题中找到了解决方案:Ninject + MVC3 is not injecting into controller

基本上,这是 Web.config 中缺少的使它起作用的东西:

<dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>

我猜这会迫使框架了解 IoC 容器,从而允许 Ninject 最终能够绑定。虽然,我不禁认为 Ninject NuGet 包应该在 Web.config 中查找该绑定重定向的存在并自动添加它。这肯定会帮助解决这个问题。

附:从我链接的那个帖子中投票赞成,因为它值得!

【讨论】:

  • 我遇到了同样的问题。希望两者之一(VS 2012 或 Ninject)能解决问题。
  • 我的mvc4项目没有漏掉这一行,但是还是不行。
  • 正是我需要的!
  • 这对我来说是固定的,除了我使用的是 Mvc 5.0.0.0
  • 我缺少对 Ninject.Web.Mvc 的引用,并且 bin 文件夹中也没有 Ninject.Web.Mvc.dll。添加了参考并解决了问题。
【解决方案2】:

从 NuGet 获取 MVC3 后,我收到了相同的错误消息。
我不知道您是否以与我相同的方式设置项目,但我的 web.config 是根据环境自动生成的。 NuGet 的 MVC 正在将 rows (&lt;runtime&gt;) 添加到 web.config 中,并且由于我的合并配置文件设置不正确,这些行已被删除。

问候,

【讨论】:

  • 我必须将 元素添加到我的 Web 配置中。以及确保 具有 targetFramework="4.5" 属性。这是我的运行时元素。
  • 喜欢@Michael,我需要添加运行时以及程序集绑定元素。 Ninject.MVC4
【解决方案3】:

我知道这是一个老问题,但似乎没有任何真正的答案,我已经解决了这个问题,所以这是我的解决方案:

创建自定义控制器工厂:

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel ninjectKernel;
    public NinjectControllerFactory(IKernel kernel)
    {
        ninjectKernel = kernel;
    }
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return (controllerType == null) ? null : (IController) ninjectKernel.Get(controllerType);
    }
}

然后,如果您使用的是 NinjectHttpApplication,请在 OnApplicationStarted 中添加以下行:

ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(Kernel));

如果您没有使用 NinjectHttpApplication,则在您创建内核后添加该行并将其传递给新创建的内核的引用。

就是这样。

【讨论】:

  • 太棒了!伙计,你刚刚拯救了我的一天。非常感谢!我花时间试图解决这个问题,这解决了它。顺便说一句,我真的很想知道为什么会发生这种情况,以及你基本上用这段代码做什么。
  • 就我而言,我必须使用如下代码:“DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));”在 NinjectWebCommon 的 Start 方法中。如果我用您的建议替换 NinjectWebCommon,我不知道将这段代码移到哪里。如果我尝试在 global.asax 中移动它,我会收到一条错误消息,告诉我在应用程序启动中注册模块的过程太晚了。这就是为什么 Ninject 的大佬建议我继续使用 NinjectWebCommon 的解决方案。
  • 这会导致 ASP MVC5、Ninject3.2、Ninject.MVC3 出现警告:“不要将 Ninject 用作​​服务定位器”。此解决方案看起来像是一种解决方法。
【解决方案4】:

在我最近从 MVC 3 转移到 MVC 4 的一个项目中,我为此花了几个小时的时间。由于缺乏正确的答案,我认为这必须是我所做的事情,因为看起来 Ninject .MVC3 nuget 包可以与 MVC 4 一起正常工作 - 确实如此。

就我而言,我并没有完全升级 MVC3 项目。在关注this guide 之后,我得到了按预期工作的东西。我的猜测是我错过了程序集绑定重定向。

因此,如果您将 MVC 3 项目升级到 MVC 4,使用 Ninject 并遇到 no parameterless constructor defined 错误,希望这会有所帮助。

【讨论】:

    【解决方案5】:

    正如所有以前的海报所说,这让我有些白发。就我而言,我已经“优化”了我的参考资料太多。 Ninject.* 东西在那里,但已经被弄乱了。我删除了所有引用并手动清理了 packages.conf 并再次添加了包 - 胜利!

    【讨论】:

      【解决方案6】:

      这是一个肮脏的解决方案! 放这个

      var type = typeof(Ninject.Web.Mvc.MvcModule);
      

      在 AppStart 事件的开头(或其他任何地方)

      现在让我解释一下如果有人还没有上钩意味着什么。 问题是我们的 http 应用程序类可以驻留在解决方案中的任何位置。不仅在 Web 应用程序中。这是非常重要的 因为 asp.net 编译例程不同于通常的库应用程序。它通过 BuildManager 帮助程序急切地加载所有引用的库,而通常 clr 不会从头开始加载类型,除非它们被直接使用。

      现在让我们回到我们的情况:Ninject.Web.Mvc 作为动态插件工作,不需要在代码中提及任何内容。因此,如果它在类库中被引用,则不会加载,这会导致 Mvc.Dependancy 初始化中断。

      【讨论】:

        【解决方案7】:

        当使用带有 ASP.NET 4.0/4.5 的 Visual Studio 2012/2013 时,似乎会出现问题。 System.Web.Mvc 的版本在 Web.config 文件中设置为 4.0.0.0。它不起作用。

        我的解决方案是

        1. 删除NinjectWebCommon.cs
        2. 将 Dere Jone 的 NinjectControllerFactory 类复制到项目中:

          public class NinjectControllerFactory : DefaultControllerFactory
          {
             private IKernel ninjectKernel;
             public NinjectControllerFactory(IKernel kernel)
             {
                ninjectKernel = kernel;
             }
          
             protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
             {
                return (controllerType == null) ? null : (IController) ninjectKernel.Get(controllerType);
             }
          }
          
        3. Global.asax的内容改为:

          public class MvcApplication : NinjectHttpApplication
          {
             protected override IKernel CreateKernel()
             {
                 IKernel kernel = new StandardKernel();
          
                 // kernel.Load(Assembly.GetExecutingAssembly());
          
                 // kernel.Bind<ISomeClass>().To<SomeClass>();
          
                 return kernel;
             }
          
             protected override void OnApplicationStarted()
             {
                 AreaRegistration.RegisterAllAreas();
          
                 WebApiConfig.Register(GlobalConfiguration.Configuration);
                 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                 RouteConfig.RegisterRoutes(RouteTable.Routes);
                 BundleConfig.RegisterBundles(BundleTable.Bundles);
          
                 ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(Kernel));
             }
          }
          

          之后,您的注射应该会起作用。

        【讨论】:

          【解决方案8】:

          我有同样的问题,唯一对我有用的是将 Web 项目属性中的“本地 IIS Web 服务器”更改为“使用 Visual Studio 开发服务器”。

          我不知道为什么,但是当我这样做时,我在 NinjectWebCommon 中的断点被击中。就像@Alex 所说,每次构建应用程序时,Visual Studio 2012 的亮度不足以在 NinjectWebCommon 中执行代码。也有可能是我不够聪明,无法理解它是如何工作的。

          我不喜欢我的解决方案,因为我更喜欢使用我的本地 IIS Web 服务器,但目前,我有一个应用程序要创建,并且花费了很多时间来使用这个 $%?!!/bug..feature。 .不确定。

          【讨论】:

          • 确保您的Web.config 中有&lt;dependentAssembly&gt; 部分。我的项目在本地 IIS 和该设置下运行得很好。当然,绑定重定向现在应该是&lt;bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" /&gt;,因为 MVC 5.1 已经发布了。
          【解决方案9】:

          通过 Nuget 添加对 Ninject.Web.MVC 的引用为我解决了这个问题。

          【讨论】:

            【解决方案10】:

            我尝试了所有这些解决方案,但都没有奏效。

            我是这样解决的: 删除了我所有的临时 asp.net 文件。完成此操作后,我收到了新的配置错误。我修好了它们。最后一个真正的错误出现了:new Bootstrapper() 试图加载一个旧版本的 ninject dll。 删除了所有 ninject 包。 一一安装了ninject nuget包,三重确保安装了正确的版本。

            【讨论】:

              【解决方案11】:

              我尝试使用 MVC 5 设置 Ninject。最后我必须先使用带有控制器工厂的解决方案,然后再使用带有绑定重定向的解决方案。之后,一切都按预期工作。使用本地 IIS 服务器。

              【讨论】:

              • 我现在正在处理的项目是针对 MVC 5 (5.1.2) 的,我不必使用控制器工厂。我只有绑定重定向,一切都很好。我也在使用本地 IIS 服务器。不过,我确实将 Ninject 代码从 MVC 项目中拆分出来并放入了它自己的项目中。
              【解决方案12】:

              整个事情太荒谬了,我切换到 Autofac,厌倦了从来没有一次能够成功地将 Ninject 添加到项目中。 Web API、MVC4、MVC5都有问题。

              对于 MVC5 人员,使用 Ninject MVC3,将以下内容添加到 web.config 应用程序级别:

               <runtime>
                      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
                          <dependentAssembly>
                              <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
                              <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
                          </dependentAssembly>
                          <dependentAssembly>
                              <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
                              <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
                          </dependentAssembly>
                          <dependentAssembly>
                              <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
                              <bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0"/>
                          </dependentAssembly>
                      </assemblyBinding>
                  </runtime>
              

              【讨论】:

                【解决方案13】:

                不要重新发明轮子,只需尝试 Install-Package Ninject.MVC3

                【讨论】:

                • 这是正确的答案。我做了 Install-Package Ninject.MVC5 并且成功了。
                • 成功了。只需卸载 Ninject MVC 3,再次安装,重建整个解决方案,运行并修复
                【解决方案14】:

                通过从我的控制器构造函数中删除 #if #endif 指令,我能够在 MVC5 Web 项目中解决此问题。

                【讨论】:

                  【解决方案15】:

                  所有这一切的捷径:下载以下 Nuget 包之一:

                  • Ninject.MVC3
                  • Ninject.MVC5

                  这将处理您需要的绑定。

                  【讨论】:

                    【解决方案16】:

                    我通过从 Nuget 移除 Ninject MVC5 并安装 Ninject MVC3 来修复我的问题。

                    MVC5 == Ninject.MVC5
                    MVC4 == Ninject.MVC3
                    MVC3 == Ninject.MVC3
                    

                    检查参考中 System.Web.MVC 的版本,以确定您当前使用的 MVC 版本。

                    【讨论】:

                      【解决方案17】:

                      我遇到了这个问题,但仅限于 Web 服务调用。在这个答案https://stackoverflow.com/a/12379938/129580 上找到了我的解决方案,下面是提供的示例代码

                      public class Service : WebService
                      {
                        public IContextProvider ContextProvider {get;set;}
                      
                        public Service()
                        {
                          ContextProvider = DependencyResolver.Current.GetService<IContextProvider>();
                        }
                      }
                      

                      后来我变成了,希望这会有所帮助......

                      /// <summary>
                      /// Summary description for PartMarking
                      /// </summary>
                      [WebService(Namespace = "http://tempuri.org/")]
                      [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
                      [System.ComponentModel.ToolboxItem(false)]
                      // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
                      [System.Web.Script.Services.ScriptService]
                      public class PartMarking : System.Web.Services.WebService
                      {
                          private readonly IUnitOfWork _unitOfWork;
                      
                          public PartMarking()
                          {
                              _unitOfWork = DependencyResolver.Current.GetService<IUnitOfWork>();
                          }
                      
                          [WebMethod]
                          public DataSet GetParentConfigurations(string engineModel, string componentCode)
                          {
                              var results = _unitOfWork.PartMarking.GetParentSicMarkings(engineModel, componentCode);
                              return results;
                          }
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2010-11-24
                        • 2013-04-25
                        • 1970-01-01
                        • 2018-02-11
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多