Antworten:
Im Allgemeinen stelle ich fest, dass es sich um ein Code-Gen-Problem handelt, und meistens liegt es daran, dass ich einen Typnamenkonflikt habe, den ich nicht lösen konnte.
Wenn Sie mit der rechten Maustaste auf Ihre Dienstreferenz klicken und auf " Konfigurieren " klicken und "Typen in referenzierten Baugruppen wiederverwenden " deaktivieren , wird das Problem wahrscheinlich behoben .
Wenn Sie einen Aspekt dieser Funktion verwendet haben, müssen Sie möglicherweise sicherstellen, dass Ihre Namen bereinigt werden.
Wie die akzeptierte Antwort zeigt, ist wahrscheinlich ein Typreferenzproblem bei der Wiederverwendung von Typen der Schuldige. Ich habe festgestellt, dass die Verwendung der Befehlszeile svcutil.exe Ihnen hilft, das zugrunde liegende Problem aufzudecken, wenn Sie das Problem nicht einfach feststellen können (wie John Saunders betont).
Als Erweiterung finden Sie hier ein kurzes Beispiel für die Verwendung von svcutil.
svcutil /t:code https://secure.myserver.com/services/MyService.svc /d:test /r:"C:\MyCode\MyAssembly\bin\debug\MyAssembly.dll"
Wo:
Vollständige svcutil-Befehlszeilenreferenz hier: http://msdn.microsoft.com/en-us/library/aa347733.aspx
Sobald Sie svcutil ausführen, sollte die Ausnahme beim Import ausgelöst werden. Möglicherweise erhalten Sie diese Art von Nachricht zu einem Ihrer Typen: "Der referenzierte Typ kann nicht verwendet werden, da er nicht mit dem importierten DataContract übereinstimmt."
Dies kann einfach so sein, wie es darin angegeben ist, dass sich einer der Typen in der referenzierten Assembly von dem unterscheidet, was im DataContract für den Service generiert wurde. In meinem Fall hatte der Dienst, den ich importierte, neuere, aktualisierte Typen von dem, was ich in der freigegebenen Assembly hatte. Dies war nicht ohne weiteres ersichtlich, da der in der Ausnahme erwähnte Typ der gleiche zu sein schien. Was anders war, war einer der verschachtelten komplexen Typen, die vom Typ verwendet wurden.
Es gibt andere komplexere Szenarien, die diese Art von Ausnahme und die daraus resultierende leere Referenz.cs auslösen können. Hier ist ein Beispiel .
Wenn dieses Problem auftritt und Sie weder generische Typen in Ihren Datenverträgen verwenden noch IsReference = true verwenden, sollten Sie sicherstellen, dass Ihre freigegebenen Typen auf Ihrem Client und Server genau gleich sind. Andernfalls wird dieses Problem wahrscheinlich auftreten.
Überprüfen Sie in diesem Fall im Fehlerfenster und im Ausgabefenster, ob Fehlermeldungen vorliegen. Wenn dies nicht hilft, versuchen Sie es svcutil.exe
manuell und prüfen Sie, ob Fehlermeldungen vorliegen.
Ich habe einen ganzen Tag lang mit genau diesem Problem meinen Kopf geschlagen. Ich habe es gerade behoben. Hier ist wie...
Der Dienst musste über SSL ausgeführt werden (dh unter https://mydomain.com/MyService.svc ).
Das Hinzufügen eines Dienstverweises zum WCF-Dienst auf einem Entwicklungsserver hat einwandfrei funktioniert.
Wenn Sie genau denselben Build des WCF-Dienstes auf dem Live-Produktionsserver bereitstellen, dann zur Clientanwendung wechseln und die Dienstreferenz so konfigurieren, dass sie auf den Live-Dienst verweist, werden keine Fehler angezeigt, aber die App wird nicht erstellt: Es stellt sich heraus, dass die Dienstreferenz erstellt wurde Die Datei Reference.cs war vollständig leer! Das Aktualisieren der Servicereferenz machte keinen Unterschied. Das Reinigen der Lösung hat nicht geholfen. Ein Neustart von VS2010 machte keinen Unterschied. Das Erstellen einer neuen leeren Lösung, das Starten eines Konsolenprojekts und das Hinzufügen eines Dienstverweises zum Live-Dienst zeigten genau das gleiche Problem.
Ich dachte nicht, dass es an widersprüchlichen Typen oder irgendetwas liegt, aber was solls - ich habe die WCF-Dienstreferenz neu konfiguriert, indem ich "Typen in allen Assemblys wiederverwenden" deaktiviert habe. Keine Freude; Ich setze das Häkchen zurück.
Der nächste Schritt bestand darin, svcutil unter der Referenz-URL zu testen , um festzustellen , ob dies zur Aufdeckung des Problems beitragen würde. Hier ist der Befehl:
svcutil /t:code https://mydomain.com/MyService.svc /d:D:\test
Dies ergab Folgendes:
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.
Das hatte mich völlig verblüfft. Trotz heftigem googeln und wirklich ziemlich böse zu werden und eine Karriere als Busfahrer zu überdenken, überlegte ich schließlich, warum es auf der Entwicklungsbox in Ordnung war. Könnte es sich um ein IIS-Konfigurationsproblem handeln?
Ich habe gleichzeitig ein Remoting in die Entwicklungs- und Live-Box durchgeführt und auf jedem den IIS-Manager gestartet (mit IIS 7.5). Als nächstes ging ich jede Konfigurationseinstellung auf jeder Box durch und verglich die Werte auf jedem Server.
Und es gibt das Problem: Stellen Sie unter "SSL-Einstellungen" für die Site sicher, dass "SSL erforderlich" aktiviert ist, und aktivieren Sie das Optionsfeld "Client-Zertifikate" für "Akzeptieren". Problem gelöst!
Ich habe festgestellt, dass dies häufig auftritt, wenn ich eine Referenz hinzufüge, entferne und dann einen Dienst mit demselben Namen erneut hinzufüge. Die Typkonflikte scheinen darauf zurückzuführen zu sein, dass die alten Dateien an einer Stelle verbleiben, die Visual Studio noch sehen kann. Alles, was ich tun muss, um das Problem zu beheben, ist eine Bereinigung, bevor ich die neue Referenz hinzufüge.
Hoffe das hilft.
Ich hatte dieses Problem mit einem Silverlight 5, das von einer früheren Version aktualisiert wurde.
Selbst wenn ich die Servicereferenz erneut hinzufügte, erhielt ich immer noch eine leere Reference.cs
Am Ende musste ich ein brandneues Projekt erstellen und die Servicereferenz neu erstellen. Dies ist etwas zu versuchen, wenn Sie mehr als eine halbe Stunde damit verbracht haben. Selbst wenn Sie entschlossen sind, das ursprüngliche Projekt zu beheben, sollten Sie dies versuchen, um zu sehen, was passiert, und dann rückwärts arbeiten, um das Problem zu beheben.
Ich habe nie genau herausgefunden, wo das Problem lag - aber möglicherweise wurde etwas in der .csproj-Datei nicht aktualisiert oder eine Einstellung ist fehlgeschlagen.
System.Xml.Linq
- also überprüfe die Versionen aller deiner DLLs, wenn du die Version
Wenn Sie Ihrem Projekt kürzlich eine Sammlung hinzugefügt haben, als dies auftrat, kann das Problem durch zwei Sammlungen verursacht werden, die dasselbe CollectionDataContract- Attribut haben:
[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }
[CollectionDataContract(Name="AItems", ItemName="A")] // Wrong
public class CollectionB : List<B> { }
Ich habe den Fehler behoben, indem ich mein Projekt durchgesehen und sichergestellt habe, dass jedes Attribut Name und ItemName eindeutig ist:
[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }
[CollectionDataContract(Name="BItems", ItemName="B")] // Corrected
public class CollectionB : List<B> { }
Dann habe ich die Servicereferenz aktualisiert und alles hat wieder funktioniert.
Mein Problem war, dass ich das " mex " am Ende meines Webservice-Links belassen habe .
Anstelle von " http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex "
Verwenden Sie " http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc ".
Die Technik, die in meinem Fall für mich funktioniert hat, nachdem ich diese Antworten ohne Erfolg gelesen hatte, bestand einfach darin, meinen gesamten Vertrag zu kommentieren und Teile zu kommentieren, bis sie nicht mehr funktionieren, und zwar auf binäre Suche. Das schränkt den beleidigenden Code ein.
Dann müssen Sie nur noch raten, was mit diesem Code nicht stimmt.
Einige Fehlerrückmeldungen im Tool hätten natürlich geholfen.
Ich schreibe einen Webservicevertrag. Ich hatte eine Platzhalter-Aufzählung ohne Mitglieder. Das ist okay. Wenn ich es jedoch in einer Eigenschaft einer anderen Klasse verwende und die Vertrags-DLL auf dem Client erneut verwende, explodiert der Codegen ohne Fehlermeldung. Das Ausführen von svcutil.exe hat nicht geholfen, es konnte nur keine cs-Datei ausgegeben werden, ohne zu erwähnen, warum.
Das Folgende ist hier nicht aufgeführt und es war die Lösung, die ich gewählt habe (SvcUtils war nützlich, um die Fehlermeldung zu sehen. Der Fehler, den ich bekam, war jedoch wrapper type message cannot be projected as a data contract type since it has multiple namespaces
. Das heißt, ich folgte diesem Beispiel und erfuhr wsdl.exe
über diesen Beitrag davon).
In meinem Fall wurde durch einfaches Ausführen von wsdl [ meine-asmx-Dienstadresse ] eine problemlose .cs
Datei generiert , die ich in mein Projekt aufgenommen und zur Verwendung des Dienstes instanziiert habe.
Wie @dblood hervorhebt, liegt der Hauptschmerz im DataContractSerializer, der die Typen nicht korrekt wiederverwendet. Hier gibt es bereits einige Antworten, daher füge ich zunächst einige Vor- und Nachteile hinzu:
Glücklicherweise gibt es eine einfache Lösung, die all diese Probleme löst, wenn Sie die Kontrolle über Ihren Service haben. Dies bedeutet, dass Sie Service-Schnittstellen weiterhin über DLLs hinweg wiederverwenden können - IMO ist ein Muss für eine ordnungsgemäße Lösung. So funktioniert die Lösung:
Verwenden Sie dieselbe DLL, um den Client mit Ihrer bevorzugten Methode zu erstellen. Zum Beispiel (IMyInterface ist die Servicevertragsschnittstelle):
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();
Mit anderen Worten: Verwenden Sie nicht die Funktion "Dienstreferenz hinzufügen" , sondern zwingen Sie WCF, die (richtigen) Diensttypen zu verwenden, indem Sie die Proxy-Generierung umgehen. Immerhin haben Sie diese Klassen bereits.
Profis:
Nachteile:
Ich hatte auch das Problem defekter Service-Referenzen, wenn ich mit Projektreferenzen auf beiden Seiten arbeitete (das Service-Projekt und das Projekt, das einen Referenz auf den Service hat). Wenn die DLL des referenzierten Projekts beispielsweise "Contoso.Development.Common" heißt, der Projektname jedoch einfach auf "Common" gekürzt wird, werden auch Projektverweise auf dieses Projekt nur "Common" genannt. Der Dienst erwartet jedoch einen Verweis auf "Contoso.Development.Common" zum Auflösen von Klassen (wenn diese Option in den Dienstreferenzoptionen aktiviert ist).
Also habe ich mit dem Explorer den Ordner des Projekts geöffnet, der auf den Dienst und das "Common" -Projekt verweist. Dort bearbeite ich die VS-Projektdatei (.csproj) mit Editor. Suchen Sie nach dem Namen des referenzierten Projekts (in diesem Beispiel "Common.csproj"), und Sie finden schnell den Konfigurationseintrag, der die Projektreferenz darstellt.
ich habe mich verändert
<ProjectReference Include="..\Common\Common.csproj">
<Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project>
<Name>Common</Name>
</ProjectReference>
zu
<ProjectReference Include="..\Common\Common.csproj">
<Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project>
<Name>Contoso.Development.Common</Name>
</ProjectReference>
Wichtig ist, dass Sie den Namen der Referenz in den Namen der DLL ändern, die das referenzierte Projekt als Ausgabe hat.
Wechseln Sie dann zurück zu VS. Dort werden Sie aufgefordert, das Projekt neu zu laden, da es außerhalb von VS geändert wurde. Klicken Sie auf die Schaltfläche zum erneuten Laden.
Danach funktionierte das Hinzufügen und Aktualisieren der Dienstreferenz wie erwartet.
Hoffe das hilft auch jemand anderem.
Grüße MH
Ich hatte gestern während der Entwicklung ein ähnliches Problem. Ich fand heraus, dass ich denselben Namespace in zwei verschiedenen Vertragsversionen verwendete.
Wir haben 2 Vertragsversionen, zum Beispiel Version4 und Version5. Ich habe alle Verträge von Version 4 kopiert und den gesamten Namespace von Version 4 in Version 5 umbenannt. Dabei habe ich vergessen, den Namespace in einer der Dateien von v4 in v5 umzubenennen. Aufgrund eines Namespace-Konflikts war die Datei Reference.cs leer.
Dieses Problem ist schwer zu beheben, da beim Generieren der Dienstreferenz keine Fehlermeldung angezeigt wird. Um dieses Problem zu identifizieren, überprüfe ich manuell alle neuen Dateien, die ich erstellt habe. Es gibt andere Möglichkeiten, um dieses Problem zu lösen. Dies ist der erste Schritt, den Sie ausführen sollten, bevor Sie andere Optionen auswählen.
Vielen Dank an John Saunders Beitrag oben, der mir die Idee gab, in das Fehlerfenster zu schauen. Ich habe den ganzen Tag meinen Kopf eingesackt und im Ausgabefenster nach Fehlern gesucht.
In meinem Fall war der Täter ISerialisierbar. Ich habe eine DataContract-Klasse mit der DataMember-Eigenschaft vom Typ Exception. Sie können kein DataMember vom Typ mit dem Schlüsselwort ISerializable haben. In dieser Ausnahme hat ISerializable, sobald ich es entfernt habe, alles wie ein Zauber funktioniert.
Beim Versuch, dieses Problem zu beheben svcutil
, wurde der in der Antwort von dblood angegebene Fehler angezeigt ("Der referenzierte Typ kann nicht verwendet werden, da er nicht mit dem importierten DataContract übereinstimmt").
In meinem Fall schien die zugrunde liegende Ursache ein Aufzählungstyp zu sein, der das DataContract-Attribut hatte, dessen Mitglieder jedoch nicht mit dem EnumMember-Attribut markiert waren. Die Problemklasse, auf die svcutil
verwiesen wurde, hatte eine Eigenschaft mit diesem Aufzählungstyp.
Dies würde besser als Kommentar zu dbloods Antwort passen, aber nicht genug Repräsentanten dafür ...
In meinem Fall hatte ich eine Lösung mit dem VB Web Forms-Projekt, die auf ein C # UserControl verwies. Sowohl das VB-Projekt als auch das CS-Projekt hatten eine Dienstreferenz für denselben Dienst. Die Referenz wurde unter Service-Referenzen im VB-Projekt und unter der Gruppierung Connected Services im CS-Projekt (Framework) angezeigt.
Um die Dienstreferenz im VB-Webformularprojekt zu aktualisieren (dh die Datei Reference.vb darf nicht leer sein), musste ich das CS-Projekt entfernen, dann die VB-Dienstreferenz aktualisieren und das CS-Projekt wieder hinzufügen die Lösung.
Folge diesen Schritten:
Es scheint, dass beim Hinzufügen des Dienstes einige Verweise in diesen Ordnern verbleiben, die Fehler bei der automatischen Generierung von Code verursachen.