簡體   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