Réponses:
En général, je trouve que c'est un problème de code-gen et la plupart du temps, c'est parce que j'ai un conflit de nom de type qu'il n'a pas pu résoudre.
Si vous cliquez avec le bouton droit sur votre référence de service et cliquez sur configurer et décochez "Réutiliser les types dans les assemblys référencés", cela résoudra probablement le problème.
Si vous utilisiez un aspect de cette fonctionnalité, vous devrez peut-être vous assurer que vos noms sont nettoyés.
Comme le souligne la réponse acceptée, un problème de référence de type lors de la réutilisation de types est probablement le coupable. J'ai trouvé que lorsque vous ne pouvez pas facilement déterminer le problème, l'utilisation de la ligne de commande svcutil.exe vous aidera à révéler le problème sous-jacent (comme le souligne John Saunders).
En guise d'amélioration, voici un exemple rapide d'utilisation de svcutil.
svcutil /t:code https://secure.myserver.com/services/MyService.svc /d:test /r:"C:\MyCode\MyAssembly\bin\debug\MyAssembly.dll"
Où:
Référence complète de la ligne de commande svcutil ici: http://msdn.microsoft.com/en-us/library/aa347733.aspx
Une fois que vous exécutez svcutil, vous devriez voir l'exception levée par l'importation. Vous pouvez recevoir ce type de message concernant l'un de vos types: «Le type référencé ne peut pas être utilisé car il ne correspond pas au DataContract importé».
Cela pourrait simplement être comme spécifié dans la mesure où il existe une différence entre l'un des types de l'assembly référencé et ce qui a été généré dans le DataContract pour le service. Dans mon cas, le service que j'importait avait des types plus récents et mis à jour par rapport à ce que j'avais dans l'assembly partagé. Cela n'était pas évident car le type mentionné dans l'exception semblait être le même. Ce qui était différent était l'un des types complexes imbriqués utilisés par le type.
Il existe d'autres scénarios plus complexes qui peuvent déclencher ce type d'exception et la référence vide qui en résulte. Voici un exemple .
Si vous rencontrez ce problème et que vous n'utilisez pas de types génériques dans vos contrats de données et que vous n'utilisez pas IsReference = true, je vous recommande de vérifier avec certitude que vos types partagés sont exactement les mêmes sur votre client et votre serveur. Sinon, vous rencontrerez probablement ce problème.
Lorsque cela se produit, regardez dans la fenêtre Erreurs et la fenêtre Sortie pour voir s'il y a des messages d'erreur. Si cela ne résout pas le svcutil.exe
problème , essayez d'exécuter manuellement et voyez s'il y a des messages d'erreur.
Je me cogne la tête depuis une journée entière avec ce problème exact. Je viens de le réparer. Voici comment...
Le service devait fonctionner sur SSL (c'est-à-dire qu'il se trouve sur https://mondomaine.com/MyService.svc )
L'ajout d'une référence de service au service WCF sur un serveur de développement fonctionnait très bien.
Le déploiement de la même version exacte du service WCF sur le serveur de production en direct, puis le passage à l'application cliente et la configuration de la référence de service pour pointer vers le service en direct n'affichaient aucune erreur mais l'application ne se créerait pas: il s'avère que la référence de service est Le fichier Reference.cs était complètement vide! La mise à jour de la référence de service n'a fait aucune différence. Nettoyer la solution n'a pas aidé. Le redémarrage de VS2010 n'a fait aucune différence. La création d'une nouvelle solution vierge, le démarrage d'un projet de console et l'ajout d'une référence de service au service en direct présentaient exactement le même problème.
Je ne pensais pas que c'était dû à des types en conflit ou quoi que ce soit, mais qu'est-ce que diable - j'ai reconfiguré la référence de service WCF en décochant «Réutiliser les types dans tous les assemblys référencés». Pas de joie; J'ai remis la coche.
L'étape suivante consistait à essayer svcutil sur l'URL de référence pour voir si cela aiderait à découvrir le problème. Voici la commande:
svcutil /t:code https://mydomain.com/MyService.svc /d:D:\test
Cela a produit ce qui suit:
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 4.0.30319.1]
Copyright (c) Microsoft Corporation. All rights reserved.
Attempting to download metadata from 'https://mydomain.com/MyService.svc' using WS-Metadata Exchange or DISCO.
Error: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Schema with target namespace 'http://mynamespace.com//' could not be found.
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://mynamespace.com//']/wsdl:portType[@name='IMyService']
Error: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.
XPath to wsdl:portType: //wsdl:definitions[@targetNamespace='http://mynamespace.com//']/wsdl:portType[@name='IMyService']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='WSHttpBinding_IMyService']
Error: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.
XPath to wsdl:binding: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='WSHttpBinding_IMyService']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:service[@name='MyService']/wsdl:port[@name='WSHttpBinding_IMyService']
Generating files...
Warning: No code was generated.
If you were trying to generate a client, this could be because the metadata documents did not contain any valid contracts or services
or because all contracts/services were discovered to exist in /reference assemblies. Verify that you passed all the metadata documents to the tool.
Warning: If you would like to generate data contracts from schemas make sure to use the /dataContractOnly option.
Cela m'a complètement perplexe. Malgré de lourdes recherches sur Google et de devenir vraiment plutôt croisé, et de reconsidérer une carrière de chauffeur de bus, j'ai finalement réfléchi à la raison pour laquelle cela fonctionnait bien sur la boîte de développement. Cela pourrait-il être un problème de configuration IIS?
J'ai distant simultanément à la fois dans les boîtes de développement et en direct, et sur chacune, j'ai lancé le gestionnaire IIS (exécutant IIS 7.5). Ensuite, j'ai parcouru chaque paramètre de configuration sur chaque boîte, en comparant les valeurs sur chaque serveur.
Et il y a le problème: sous "Paramètres SSL" pour le site, assurez-vous que "Exiger SSL" est coché et cochez le bouton radio Certificats client pour "Accepter". Problème résolu!
J'ai constaté que cela se produisait fréquemment chaque fois que j'ajoute une référence, la supprime, puis rajoute un service du même nom. Les conflits de type semblent être dus au fait que les anciens fichiers restent quelque part que Visual Studio peut encore voir. Tout ce que j'ai à faire pour le réparer, c'est un nettoyage avant d'ajouter la nouvelle référence.
J'espère que cela t'aides.
J'ai eu ce problème avec un Silverlight 5 mis à niveau à partir d'une version précédente.
Même la réajout de la référence de service m'a toujours donné une référence vide.cs
J'ai fini par devoir créer un tout nouveau projet et recréer la référence du service. C'est quelque chose à essayer si vous y avez passé plus d'une demi-heure. Même si vous êtes déterminé à résoudre le projet d'origine, vous voudrez peut-être essayer ceci juste pour voir ce qui se passe, puis travailler à rebours pour essayer de résoudre le problème.
Je n'ai jamais compris exactement quel était le problème - mais peut-être que quelque chose dans le fichier .csproj n'a pas été mis à niveau ou qu'un paramètre s'est mal passé.
System.Xml.Linq
- alors vérifiez les versions de toutes vos DLL si vous avez changé de version
Si vous avez récemment ajouté une collection à votre projet lorsque cela a commencé à se produire, le problème peut être dû à deux collections qui ont le même attribut CollectionDataContract :
[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }
[CollectionDataContract(Name="AItems", ItemName="A")] // Wrong
public class CollectionB : List<B> { }
J'ai corrigé l'erreur en parcourant mon projet et en m'assurant que chaque attribut Name et ItemName était unique:
[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }
[CollectionDataContract(Name="BItems", ItemName="B")] // Corrected
public class CollectionB : List<B> { }
Ensuite, j'ai actualisé la référence du service et tout a fonctionné à nouveau.
Mon problème était que j'ai laissé le " mex " à la fin de mon lien de service Web.
Au lieu de " http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex "
Utilisez " http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc "
La technique qui a fonctionné pour moi dans mon cas, après avoir lu ces réponses en vain, était simplement de commenter tout mon contrat, et de décommenter les bits jusqu'à ce que cela ne fonctionne plus, de manière binaire. Cela réduit le morceau de code offensant.
Ensuite, il vous suffit de deviner ce qui ne va pas avec ce code.
Un retour d'erreur dans l'outil aurait bien sûr aidé.
J'écris un contrat de service Web. J'avais une énumération d'espace réservé sans membres. C'est bon. Mais si je l'utilise dans une propriété d'une autre classe et que je réutilise la DLL du contrat sur le client, le codegen explose sans message d'erreur. L'exécution de svcutil.exe n'a pas aidé, il n'a tout simplement pas réussi à générer un fichier cs sans mentionner pourquoi.
Ce qui suit n'est pas répertorié ici, et c'est la solution que j'ai adoptée (SvcUtils a été utile pour voir le message d'erreur. Cependant, l'erreur que j'ai obtenue était wrapper type message cannot be projected as a data contract type since it has multiple namespaces
. Cela signifie que j'ai suivi cette piste et j'ai appris wsdl.exe
via ce post).
Dans mon cas, le simple fait d'exécuter wsdl [ my-asmx-service-address ] a généré un .cs
fichier sans problème , que j'ai inclus dans mon projet et instancié pour utiliser le service.
Comme le souligne @dblood, le principal problème réside dans le DataContractSerializer, qui ne réutilise pas correctement les types. Il y a déjà quelques réponses ici, je vais donc commencer par ajouter quelques avantages et inconvénients à ce sujet:
Heureusement, si vous contrôlez votre service, il existe une solution simple qui résout tous ces problèmes. Cela signifie que vous pouvez toujours réutiliser les interfaces de service dans les DLL - ce qui est indispensable à l'OMI pour une solution appropriée. Voici comment fonctionne la solution:
Utilisez la même DLL pour construire le client en utilisant votre méthode préférée. Par exemple (IMyInterface est l'interface du contrat de service):
var httpBinding = new BasicHttpBinding();
var identity = new DnsEndpointIdentity("");
var address = new EndpointAddress(url, identity, new AddressHeaderCollection());
var channel = new ChannelFactory<IMyInterface>(httpBinding, address);
return channel.CreateChannel();
En d'autres termes: n'utilisez pas la fonctionnalité «ajouter une référence de service» , mais forcez WCF à utiliser les types de service (corrects) en contournant la génération de proxy. Après tout, vous avez déjà ces cours.
Avantages:
Les inconvénients:
J'ai également eu le problème des références de service cassées lorsque je travaillais avec des références de projet des deux côtés (le projet de service et le projet ayant une référence au service). Si le fichier .dll du projet référencé par exemple est appelé "Contoso.Development.Common", mais que le nom du projet est simplement raccourci en "Common", les références de projet à ce projet sont nommées simplement "Common". Le service attend cependant une référence à "Contoso.Development.Common" pour la résolution des classes (si cette option est activée dans les options de référence du service).
Donc avec l'explorateur j'ai ouvert le dossier du projet qui fait référence au service et au projet "Common". Là, j'édite le fichier de projet VS (.csproj) avec le bloc-notes. Recherchez le nom du projet référencé (qui est "Common.csproj" dans cet exemple) et vous trouverez rapidement l'entrée de configuration représentant la référence du projet.
j'ai changé
<ProjectReference Include="..\Common\Common.csproj">
<Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project>
<Name>Common</Name>
</ProjectReference>
à
<ProjectReference Include="..\Common\Common.csproj">
<Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project>
<Name>Contoso.Development.Common</Name>
</ProjectReference>
L'important est de changer le nom de la référence par le nom de la DLL que le projet référencé a en sortie.
Revenez ensuite à VS. Là, il vous sera demandé de recharger le projet car il a été modifié en dehors de VS. Cliquez sur le bouton de rechargement.
Après cela, l'ajout et la mise à jour de la référence du service ont fonctionné comme prévu.
J'espère que cela aide aussi quelqu'un d'autre.
Cordialement MH
J'ai été confronté à un problème similaire hier pendant le développement. J'ai découvert que j'utilisais le même espace de noms dans 2 versions différentes de contrats.
Nous avons 2 versions de contrats par exemple la version4 et la version5. J'ai copié tous les contrats de la version4 et renommé tout l'espace de noms de la version4 à la version5. En faisant cela, j'ai oublié de renommer l'espace de noms de la v4 à la v5 dans l'un des fichiers. En raison d'un conflit d'espace de noms, le fichier Reference.cs était vide.
Ce problème est difficile à résoudre car vous ne recevez aucun message d'erreur lors de la génération de la référence de service. Pour identifier ce problème, je validerais manuellement tous les nouveaux fichiers que j'avais créés. Il existe d'autres moyens de résoudre ce problème. C'est la première étape à effectuer avant de choisir d'autres options.
Merci au message de John Saunders ci-dessus qui m'a donné une idée de regarder dans la fenêtre d'erreur. J'emballais toute la journée ma tête et je regardais la fenêtre de sortie pour toute erreur.
Dans mon cas, le coupable était ISerializable. J'ai une classe DataContract avec la propriété DataMember de type Exception. Vous ne pouvez pas avoir de DataMember de type qui a un mot clé ISerializable. Dans cette exception a ISerializable dès que je l'ai retiré, tout fonctionnait comme un charme.
En essayant de résoudre ce problème avec svcutil
, j'ai reçu l'erreur mentionnée dans la réponse de dblood («le type référencé ne peut pas être utilisé car il ne correspond pas au DataContract importé»).
Dans mon cas, la cause sous-jacente semblait être un type enum qui avait l'attribut DataContract, mais dont les membres n'étaient pas marqués avec l'attribut EnumMember. La classe de problème svcutil
pointée avait une propriété avec ce type enum.
Cela conviendrait mieux comme commentaire à la réponse de dblood, mais pas assez de représentants pour cela ...
Dans mon cas, j'avais une solution avec le projet VB Web Forms qui faisait référence à un UserControl C #. Le projet VB et le projet CS avaient tous deux une référence de service pour le même service. La référence est apparue sous Références de service dans le projet VB et sous le regroupement Services connectés dans le projet CS (framework).
Afin de mettre à jour la référence de service (c'est-à-dire que le fichier Reference.vb ne soit pas vide) dans le projet de formulaires Web VB, j'avais besoin de SUPPRIMER LE PROJET CS, puis de mettre à jour la référence de service VB, puis de rajouter le projet CS dans la solution.
Suivez ces étapes:
Il semble que certaines références soient laissées dans ces dossiers lors de l'ajout du service, provoquant des erreurs lors de la génération automatique du code.