[英]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 object
的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 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
。 它不起作用。
我的解决方案是
NinjectWebCommon.cs
将 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); } }
将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.