繁体   English   中英

ASP.NET MVC 4 + Ninject MVC 3 = 没有为此对象定义无参数构造函数

[英]ASP.NET MVC 4 + Ninject MVC 3 = No parameterless constructor defined for this object

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

在我们开始之前,我知道这是一个非常常见的问题,我已经在许多卫星上使用 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)的其他项目的工作方式,据我所知,这是使一切正常工作所需要的。 那么,为什么我突然得到没有为此对象定义的无参数构造函数。 例外?

更新

这是完整的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();
        }
    }
}

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

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

创建自定义控制器工厂:

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,请在创建内核后在某处添加该行,并将其传递给新创建的内核的引用。

而已。

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

当 2012 调试它的项目时,它只是提出了No parameterless constructor defined for this object异常No parameterless constructor defined for this objectNo 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 injection 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 中查找该绑定重定向的存在并自动神奇地添加它。 它肯定会帮助解决这个问题上发生的大量头发问题。

PS 为我链接的那篇文章中的鼻涕点投票,因为它值得!

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

从 NuGet 获取 MVC3 后,我收到了相同的错误消息。
我不知道你的项目设置是否和我一样,但我的web.config是根据环境自动生成的。 NuGet 的 MVC 正在向web.config添加rows (<runtime>) ,并且由于我的合并配置文件设置不正确,这些行已被删除。

问候,

整件事很荒谬,我转而使用 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>

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

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

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

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

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

当使用带有 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)); } }

    之后你的注射应该有效。

我遇到了这个问题,但仅限于 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;
    }
}

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

就我而言,我没有完全升级 MVC3 项目。 遵循本指南后,我让事情按预期工作。 我的猜测是我缺少程序集绑定重定向。

因此,如果您将 MVC 3 项目升级到 MVC 4,使用 Ninject 并获得无参数构造函数定义的错误,希望这会有所帮助。

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

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

在此处输入图片说明

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

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

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

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

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

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

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

所有这些的快捷方式:下载以下 Nuget 包之一:

  • Ninject.MVC3
  • Ninject.MVC5

这将处理您需要的绑定。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM