Ninject erreur dans WebAPI 2.1 - assurez-vous que le contrôleur dispose d'un constructeur public sans paramètre
J'ai les paquets suivants et leurs dépendances installé dans mon WebAPI projet:
Ninject.Web.WebApi
Ninject.Web.WebApi.OwinHost
Je suis en cours d'exécution ce est purement un web-api projet. Pas de MVC.
Quand je lance mon application et envoyer un courrier à l'AccountController Registre de l'action, j'obtiens l'erreur suivante retourné:
{
"message":"An error has occurred.",
"exceptionMessage":"An error occurred when trying to create a controller of type 'AccountController'. Make sure that the controller has a parameterless public constructor.",
"exceptionType":"System.InvalidOperationException",
"stackTrace":" at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()",
"innerException":{
"message":"An error has occurred.",
"exceptionMessage":"Type 'RPT.Api.Controllers.AccountController' does not have a default constructor",
"exceptionType":"System.ArgumentException",
"stackTrace":" at System.Linq.Expressions.Expression.New(Type type)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
}
}
Quelqu'un peut m'aider, comme les seuls détails que je peux trouver sur Google semblent être à partir de 2012.
Remarque: j'ai aussi essayé de AutoFac au lieu de Ninject et obtenir la même erreur il y a trop. Le plus frustrant.
Voici mon NinjectWebCommon.cs:
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using RPT.Data;
using RPT.Services;
using RPT.Services.Interfaces;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(RPT.Api.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(RPT.Api.NinjectWebCommon), "Stop")]
namespace RPT.Api
{
using System;
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();
///<summary>
///Starts the application
///</summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
///<summary>
///Stops the application.
///</summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
///<summary>
///Creates the kernel that will manage your application.
///</summary>
///<returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
///<summary>
///Load your modules or register your services here!
///</summary>
///<param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<RptContext>().ToSelf();
kernel.Bind<IUserStore<IdentityUser>>().To<UserStore<IdentityUser>>();
kernel.Bind<UserManager<IdentityUser>>().ToSelf();
kernel.Bind<IAccountService>().To<AccountService>();
}
}
}
Voici mon AccountController:
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.ModelBinding;
using Microsoft.AspNet.Identity;
using RPT.Api.Models;
using RPT.Services.Interfaces;
namespace RPT.Api.Controllers
{
[RoutePrefix("api/account")]
public class AccountController : ApiController
{
#region Initialisation
private readonly IAccountService _accountService;
public AccountController(IAccountService accountService) : base()
{
_accountService = accountService;
}
#endregion
#region Actions
[AllowAnonymous]
[Route("register")]
public async Task<IHttpActionResult> Register(UserRegistrationViewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _accountService.RegisterUser(model.UserName, model.Password);
var errorResult = GetErrorResult(result);
return errorResult ?? Ok();
}
#endregion
#region Internal
protected override void Dispose(bool disposing)
{
if (disposing)
{
_accountService.Dispose();
}
base.Dispose(disposing);
}
private IHttpActionResult GetErrorResult(IdentityResult result)
{
if (result == null)
{
return InternalServerError();
}
if (result.Succeeded) return null;
if (result.Errors != null)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
if (ModelState.IsValid)
{
//No ModelState errors are available to send, so just return an empty BadRequest.
return BadRequest();
}
return BadRequest(ModelState);
}
#endregion
}
}
Ce n'est pas sûr de faire du Cio à l'aide de WebActivatorEx, mais il y a un exemple sur le web-api site qui enregistre les récipients à l'aide de IDependencyResolver. Vous pourriez peut-être modifier votre code pour implémenter cette interface à la place? asp.net/web-api/overview/extensibility/...
Ne pas le Ninject.WebApi paquet incluent un solveur de dépendances de la même manière que le Ninject.MVC3 package pour les applications MVC?
Ne pas le Ninject.WebApi paquet incluent un solveur de dépendances de la même manière que le Ninject.MVC3 package pour les applications MVC?
OriginalL'auteur Hades | 2014-06-12
Vous devez vous connecter pour publier un commentaire.
Avez-vous modifier votre OWIN
Startup
classe pour appelerapp.UseNinjectWebApi
etapp.UseNinjectMiddleware
plutôt que d'appelerapp.UseWebApi
?De démarrage.cs dans le Ninject API Web échantillons est-ce que...
Je ne suis pas sûr de l'endroit où NinjextWebCommon.cs vient - est habituellement ajouté les projets MVC? Vous pouvez configurer le noyau et ses liaisons dans l'CreateKernel méthode de Démarrage.cs
NinjectWebCommon.cs est ajouté par l'un des Ninject les packages nuget. Je pense que c'était soit Ninject.Web.WebApi.OwinHost ou Ninject.Web.WebApi.Hébergeur... ce pourrait être là où ma confusion a poussé à partir.
Eh bien, cela a fonctionné pour moi... semble que NinjectWebCommon.cs n'est tout simplement pas nécessaire avec WebAPI/OWIN configurations. Grâce muchly 🙂
Cette solution a fonctionné pour moi !!! 🙂 Une erreur a été observée lorsque tous les 3 paramètres de configuration sont en place, c'est à dire UseWebApi(), UseNinjectWebApi() et UseNinjectMiddleware() en application de démarrage de l'instance. Mais, en supprimant UseWebApi() et en utilisant seulement 2 autres paramètres résolu le problème. Nous avons été à l'aide de Ninject CIO et OWIN dans l'application. Espérons que cette information aide les personnes confrontées au même problème 🙂
OriginalL'auteur Dean Ward
Dans mon cas, la raison en était le résolveur ne pouvait pas trouver une correspondance. C'est-supposons que dire HomeController a une dépendance sur IDumb, le résolveur ne pouvait pas trouver une mise en œuvre concrète de la Muette de implémente IDumb.
En d'autres mots, le message d'erreur
est totalement trompeuse. Dans mon cas j'ai simplement résolu par l'ajout d'une référence au projet de la classe Muet. Il doit avoir été quelque chose comme "Pas de mapping pour IDumb a pu être trouvé.". Je ne suis pas sûr que le problème est avec NInject ou MME Ce que jamais, il m'a fallu des heures pour trouver ce out.
Pire message d'erreur jamais. Je vous remercie.
C'est CE qui m'a vraiment aidé. Essayez de résoudre la dépendance sur votre propre. Vous verrez qu'il échoue. Il semble que l'API Web appelle un constructeur avec seulement les dépendances, il pourrait résoudre en tant que paramètres et en ignorant les autres.
Peu vieux, mais je viens de passer des heures à la fixation d'erreur en MVC + WebApi, sont passés à Autofac, a obtenu une glorieuse exception et une heure plus tard, tout est fixe et en cours d'exécution.
Pour référence future, prendre un coup d'oeil à l'exception interne - il montre où est le problème
OriginalL'auteur VivekDev
Ma solution est d'ajouter le mot clé "public" de constructeur.
OriginalL'auteur Phan Đức Bình
Il vous manque un solveur de dépendances, ses vraiment une base de mise en œuvre:
Ensuite, il suffit de s'inscrire au moment de créer le noyau:
où voulez-vous obtenir le noyau?
OriginalL'auteur CarbonAtoms
Assurez-vous que vous avez enregistré tous les types utilisés par le contrôleur, tout le chemin jusqu'à la base de données.
Dans mon cas, j'avais ajouté de l'interface que le contrôleur lui-même, mais pas l'interface de requête de la base de données.
Avis dans le code ci-dessous comment le AddUserMaintenanceProcessor classe a des dépendances que le contrôleur ne sais pas. Si vous omettez l'Unité (ou quel que soit Cio outil que vous utilisez) type de correspondances de ces dépendances, le contrôleur de la construction sera un échec.
Ma solution utilise l'Unité, mais le point que j'essaie de faire, c'est que vous avez besoin pour créer des mappages de type pour toutes les dépendances.
De démarrage.cs
UnityConfig.cs
UsersController.cs
AddUserMaintenanceProcessor.cs
J'ai omis les interfaces pour les processeurs comme ils ne contiennent qu'une seule méthode (modèle de Stratégie). Les interfaces pour l'enregistrement et le mappage automatique ne sont pas pertinents à cette question.
La AddUserQueryProcessor classe continue simplement à l'utilisateur de la base de données. Une fois de plus pertinent pour cette question.
OriginalL'auteur Niclas Lindstedt
Pour moi, ce qui a provoqué cette erreur a été que pour l'interface, j'étais de passage dans le constructeur, j'avais un nom de liaison et je l'ai appelé avec le mauvais nom. Comme vous pouvez le voir ci-dessous, la liaison dit qu'il a nommé "l'Entrepôt", mais j'ai eu des choses mélangées et mis "DataWarehouse" dans le constructeur. L'obtention de cette redressé l'origine de l'erreur à propos d'un constructeur sans paramètre de s'en aller.
constructeur:
OriginalL'auteur Kelly