Parfois, l'ajout d'une référence de service WCF génère une référence vide.

159

Parfois, l'ajout d'une référence de service WCF génère une référence.cs vide et je ne peux pas référencer le service n'importe où dans le projet.

Quelqu'un at-il rencontré cela?

Mat
la source

Réponses:

377

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.

Anderson Imes
la source
5
Quand cela m'est arrivé, j'ai trouvé que je devais également changer le type de collection d'ObjectModel.ObservableCollection en Generic.List
Yossi Dahan
2
Cela m'est arrivé parce que j'ai ajouté à la classe partielle.
Makotosan
2
Cependant, si vous souhaitez utiliser des types d'un assemblage spécifique, vous pouvez sélectionner uniquement cet assemblage et cela fonctionne tout aussi bien (du moins dans mon cas), ta
Dead.Rabit
26
Cela me stupéfie de savoir que j'obtiens en moyenne 50 points par semaine à partir de cette question, même 6 ans plus tard. Allez MS, corrige ça. Au moins, donnez aux développeurs des commentaires lorsque cela se passe mal au lieu de leur demander de regarder un fichier vide.
Anderson Imes
1
9 ans plus tard et vous aidez toujours. Je vous remercie!
paramètre
38

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ù:

  • / t: le code génère le code à partir de l'url donnée
  • / d: pour spécifier le répertoire de la sortie
  • / r: pour spécifier un assemblage de référence

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.

dblood
la source
Dans mon cas, cela s'est produit après avoir référencé un assembly qui faisait également référence à mon service WCF. La suppression de cet assembly de la liste des assemblys pour partager des types avec l'a corrigé.
xr280xr
J'obtenais un message d'erreur sans signification (juste un espace de noms) lors de l'ajout d'une référence de service et cela a souligné le problème.
bcampolo
12

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.exeproblème , essayez d'exécuter manuellement et voyez s'il y a des messages d'erreur.

John Saunders
la source
@ Comment exécuter svcutil.exe? Pouvez-vous m'aider ?
Arul Sidthan
@Arul: utilisez Google pour trouver des informations sur svcutil.exe.
John Saunders
2
Je ne sais pas si Microsoft a lu cet article, mais même en affichant simplement une boîte de message indiquant les erreurs et les avertissements au lieu de simplement les mettre silencieusement dans la fenêtre (minimisée, dans mon cas) Liste des erreurs l'aurait fait, donc je n'avais pas besoin de Google ce. Sinon, je suppose qu'il serait utile que l'onglet s'affiche en rouge ou en jaune lorsqu'il y a de nouveaux avertissements / erreurs?
jrh
12

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!

Matt Kane
la source
5

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.

  1. Supprimez la référence de service ayant des problèmes.
  2. Cliquez sur le nom du projet dans l' Explorateur de solutions pour mettre le projet en surbrillance.
  3. Cliquez avec le bouton droit sur la référence du projet.
  4. En haut de la liste contextuelle, cliquez sur l' élément Nettoyer .
  5. Ajoutez votre référence de service comme vous le feriez normalement.

J'espère que cela t'aides.

user1353936
la source
3

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é.

Simon_Weaver
la source
1
ok il s'est avéré que je faisais référence à une ancienne version de System.Xml.Linq- alors vérifiez les versions de toutes vos DLL si vous avez changé de version
Simon_Weaver
1

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.

Jon Person
la source
1

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.

JoshuaLawrence
la source
Commenter tous les contrats d'exploitation a fonctionné pour moi. Je regardais les mauvaises méthodes comme coupables. Merci pour l'approche de retour aux bases du dépannage.
fizch
1

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.exevia ce post).

Dans mon cas, le simple fait d'exécuter wsdl [ my-asmx-service-address ] a généré un .csfichier sans problème , que j'ai inclus dans mon projet et instancié pour utiliser le service.

Veverke
la source
0

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:

  • Le drapeau 'IsReference' cause beaucoup de problèmes, mais le supprimer n'est pas toujours la réponse (en particulier: dans les situations de récursivité).
  • Le problème sous-jacent est que le contrat de données n'est pas le même que les noms de types, même s'ils le sont parfois (hein? Oui, vous avez bien lu!). Apparemment, le sérialiseur est assez difficile et il est très difficile de trouver le vrai problème.
  • La suppression des «vérifications de références» de «Configurer la référence de service» fonctionne, mais vous laisse avec plusieurs implémentations. Cependant, je réutilise souvent les interfaces SOAP entre les DLL. De plus, dans la plupart des SOA matures que je connais, plusieurs interfaces de services implémentent et étendent les mêmes classes d'interface. La suppression des vérifications «utiliser des types référencés» entraîne une situation dans laquelle vous ne pouvez plus simplement passer des objets.

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:

  1. Créez une DLL d'interface distincte. Dans cette DLL, incluez tous les DataContract et ServiceContract; mettez ServiceContract sur vos interfaces.
  2. Dérivez l'implémentation du serveur de l'interface.
  3. 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:

  1. Vous contournez le processus svcutil.exe, ce qui signifie que vous n'avez aucun problème IsReference
  2. Les types et les noms de DataContract sont corrects par définition; après tout, le serveur et le client utilisent la même définition.
  3. Si vous étendez l'API ou utilisez des types d'une autre DLL, (1) et (2) sont toujours valables, vous ne rencontrerez donc aucun problème.

Les inconvénients:

  1. Les méthodes A-sync sont pénibles, car vous ne générez pas de proxy a-sync. Par conséquent, je ne recommanderais pas de le faire dans les applications Silverlight.
goûter
la source
0

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

Martype
la source
0

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.

arif.khan.b
la source
0

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.

Ziggler
la source
0

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 svcutilpointé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 ...

Platedslicer
la source
0

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.

INFOequipt
la source
0

Suivez ces étapes:

  1. Supprimer la référence de service
  2. Fermer Visual Studio
  3. Supprimez les dossiers / Bin et / Obj.
  4. Ouvrez Visual Studio.
  5. Ajoutez la référence de service.
  6. De rien :)

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.

Exel Gamboa
la source