Comment configurer Web Api 2 à regarder pour les Contrôleurs dans un autre projet? (tout comme j'ai l'habitude de faire dans l'Api Web)
J'ai utilisé à la place de mon contrôleurs dans un projet de Bibliothèque de classes dans Mvc, Web Api. J'ai utilisé pour ajouter la ligne suivante dans mon api web du projet global.asax de regarder pour les contrôleurs dans le projet:
ControllerBuilder.Current.DefaultNamespaces.Add("MyClassLibraryProject.Controllers");
Je n'ai jamais eu à faire toute autre configuration, sauf pour ajouter la ligne ci-dessus. Cela a toujours fonctionné pour moi.
Cependant, je ne peux pas utiliser la méthode ci-dessus pour faire la même chose dans WebApi2. Il ne fonctionne tout simplement pas. Le WebApi2 projet tente encore de trouver les contrôleurs dans son propre projet du dossier controllers.
- En donnant à petit résumé de mise à jour au bout de 2 mois (j'ai commencé prime sur ce):
J'ai créé un WebApiOne solution, il dispose de 2 projets, le premier est WebApi, et le deuxième est une bibliothèque de classes pour les contrôleurs. Si j'ajoute la référence à l'contrôleurs projet de bibliothèque de classes dans la WebApi projet, tout fonctionne comme prévu. c'est à dire si je vais à http://mydevdomain.com/api/values je peux voir le bon de sortie.
J'ai maintenant créer un deuxième projet appelé WebApiTwo, il dispose de 2 projets, le premier est WebApi2 projet, et la seconde est une bibliothèque de classes pour les contrôleurs. Si j'ajoute la référence à l'contrôleurs projet de bibliothèque de classes pour la WebApi2 projet, il fais PAS fonctionner comme prévu. c'est à dire si je vais à http://mydevdomain.com/api/values j'ai "Aucun type a été trouvé qui correspond le contrôleur nommé des "valeurs"."
pour le premier projet que je ne le fais pas tous les paramètres personnalisés à tous, je n'ai PAS:
ControllerBuilder.Current.DefaultNamespaces.Add("MyClassLibraryProject.Controllers");
dans mon global.asax, et je n'ai pas mis en œuvre de solutions personnalisées proposées par StrathWeb dans deux de ses articles de blog, car je pense que sa ne s'applique plus; parce que tous les travaux juste en ajoutant la référence du contrôleur de projet à la WebApi projet.
Donc je m'attends tout de même pour WebApi2 ... mais pas. Quelqu'un a vraiment essayé de faire cela dans WebAPi2 ?
- Le code que tu montre est liée à des contrôleurs MVC qui n'a rien à voir avec l'API Web. Aussi longtemps que l'assemblée avec vos contrôleurs d'API Web a été chargé les Contrôleurs être trouvé.
- +1 sur ce que Darrel est de mentionner
- Cela peut vous donner quelques conseils sur ce que vous essayez de faire: strathweb.com/2013/08/...
- merci ... que signifie alors qu'il travaillait en MVC4 et ne travaille PAS dans MVC5 ... je viens de créer deux temp projets pour démontrer cela, MVC4 avec WebApi est certainement de travail, mais MVC5 avec WebApi2 n'est pas ...
- WebApi1 et WebApi2 les deux contrôleurs de charge de TOUS les assemblys chargés. Et d'autres que d'être regroupés dans un template, Web API de base zéro de la dépendance sur MVC. Vous avez besoin de savoir pourquoi votre contrôleur de l'assemblée n'est pas en cours de chargement.
- les assemblages sont certainement chargement. je viens de faire ceci: var loadedAssemblies = domaine d'application.CurrentDomain.GetAssemblies(); et je peux voir mes contrôleurs assembler là ... ne peux pas obtenir ce pour travailler dans le web api2. d'autres idées ???
- C'est un long shot, mais je dois poser la question - sont les classes de contrôleur et de méthodes MyClassLibraryProject.Les contrôleurs marqué en tant que public?
- Cela devrait fonctionner out-of-the-box. J'ai fait un million de fois. Le
Web Api
de l'infrastructure des scans de toutes les assemblées chargées dans leAppDomain
et ajoute toutes les classes qui héritent deApiController
pour le contrôleur de collection. Je pense que quelque chose d'autre se passe. - Alors, permettez-moi obtenir ce droit. Votre 1ère solution était dans WebApi v1, et le 2ème était dans WebApi v2, droit? J'ai essayé de reproduire le problème à l'aide de WebApi v2 (vs2013), que par la façon dont votre procédure mentionnée, cependant, j'ai été en mesure d'obtenir une réponse de mon contrôleur.
Vous devez vous connecter pour publier un commentaire.
J'ai juste confirmé que cela fonctionne bien. Les choses à vérifier:
Références: votre principal projet d'API Web de référence de la classe externe de la bibliothèque?
De routage: Avez-vous mis en place des itinéraires qui pourraient interférer avec les contrôleurs externes?
Niveau de Protection: Sont les contrôleurs de la bibliothèque externe
public
?Héritage: Ne les contrôleurs de la bibliothèque externe hériter de
ApiController
?Versions: Sont à la fois votre projet d'API Web et de la bibliothèque de la classe en utilisant la même version de l'API Web des bibliothèques?
Si cela peut aider, je peux package de ma solution de test et de le rendre disponible pour vous.
Aussi, comme un point à noter, vous n'avez pas besoin de dire à l'API Web pour trouver les contrôleurs de la ligne que vous avez ajouté à
Global.asax
, le système repère les contrôleurs automatiquement à condition de les avoir référencés.Il doit travailler comme est. Liste de contrôle
ApiController
ValuesController
Clean
la solution, supprimer manuellementbin
dossiers et de reconstruireTemporary ASP.NET Files
dossiers. WebApi et MVC cache de contrôleur de résultat de rechercheCe contrôleur:
correspond à cette url:
http://localhost/MyValues/Get
(remarque il n'est pas/api/
en route parce qu'il n'était pas spécifié dansRoutePrefix
.Contrôleur de recherche de mise en cache:
C'est de contrôleur par défaut du résolveur. Vous verrez dans le code source qu'il les caches de résultat de recherche.
/api/cars
, un contrôleur externe dans une assemblée appelée CarApiController et décorées avec[RoutePrefix("/api/cars")]
n'a pas de travail, mais simplement de changer le nom de la classe àCarsController
fait le travail. Étrange, mais peut-être que quelqu'un peut expliquer cela.Était en cours d'exécution en même scénario et @justmara placez-moi sur le droit chemin. Voici comment pour accomplir la force de chargement de l'objet dépendant des assemblages à partir de @justmara réponse:
1) Remplacer les DefaultAssembliesResolver classe
2) Dans la section de configuration, remplacez la valeur par défaut avec la nouvelle mise en œuvre
Je pavées de cette syntaxe ensemble à l'aide de pointeurs à partir de ce blog:
http://www.strathweb.com/2013/08/customizing-controller-discovery-in-asp-net-web-api/
Comme d'autres l'ont dit, vous savez si vous rencontrez ce problème si vous forcez le contrôleur de charge directement par le référençant. Une autre façon est d'exemple les résultats de
CurrentDomain.GetAssemblies()
et de voir si votre assemblée est dans la liste.Aussi: Si vous êtes auto-hébergement à l'aide de OWIN composants vous PERMETTRA de lancer dans ce. Lors de l'essai de garder à l'esprit que la DefaultAssembliesResolver ne seront PAS coup de pied jusqu'à ce que la première WebAPI demande est présentée (il m'a fallu un certain temps pour réaliser que).
virtual
->override
). Si vous faites cela, le code fonctionne, mais comme l'a souligné avant,assemblies
n'est pas utilisé. Supprimer cette cession, ou de corriger l'utilisation, c'est à dire changer l'appel àbaseAssemblies.Add
enassemblies.Add
puis retourassemblies
, pasbaseAssemblies
.Êtes-vous sûr que votre assembly référencé a été chargée AVANT de IAssembliesResolver service appelé?
Essayez d'insérer quelques mannequin de code dans votre application, quelque chose comme
var a = new MyClassLibraryProject.Controllers.MyClass();
dans la méthode de configuration (mais n'oubliez pas, que le compilateur peut "optimiser" le présent code et les supprimer totalement, si "a" n'est jamais utilisé).
J'ai eu le même problème avec l'assemblée de l'ordre de chargement. Il a terminé avec force le chargement dépendant des assemblées de démarrage.
Vous devez dire à webapi/mvc pour charger votre referrenced de l'assemblée. Vous n'avez qu'à la compilation/assemblées de section dans votre site web.config.
Simple que cela. Vous pouvez le faire avec du code, de la façon @user1821052 suggéré, mais ce web.config version aura le même effet.
En dehors de ce qui a été déjà dit:
Assurez-vous que vous n'avez pas de deux contrôleurs du même nom dans différents espaces de noms.
Juste eu le cas où un contrôleur (foo.UserApiController) devrait être partiellement migré vers un nouvel espace de noms (de la barre.UserApiController) et URI. L'ancien contrôleur a été cartographiée par convention /userapi, la nouvelle fut attribut-routés via
RoutePrefix["api/users"]
. Le nouveau contrôleur n'a pas fonctionné jusqu'à ce que je l'ai renommé à la barre.UserFooApiController.Lors de l'utilisation de AttributeRouting il est facilement oubliable pour décorer vos méthodes avec la
Route
Attribut, en particulier lorsque vous êtes à l'aide de laRoutePrefix
Attribut sur votre contrôleur de classe. Il semble que votre contrôleur de l'assemblée n'a pas été capté par le pipeline api web alors.Si votre bibliothèque de classe est construit avec
EF
alors assurez-vous d'avoir la chaîne de connexion spécifié dans leApp.config
pour le projet de bibliothèque de classes, ET dans leWeb.config
pour votre site Web APIMVC
projet.