Manchmal generiert das Hinzufügen einer WCF-Dienstreferenz eine leere Referenz.cs

159

Manchmal generiert das Hinzufügen einer WCF-Dienstreferenz eine leere Referenz.cs, und ich kann den Dienst nirgendwo im Projekt referenzieren.

Hat jemand dies angetroffen?

Matt
quelle

Antworten:

377

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.

Anderson Imes
quelle
5
Als es mir passierte, stellte ich fest, dass ich auch den Sammlungstyp von ObjectModel.ObservableCollection in Generic.List
Yossi Dahan
2
Ist mir passiert, weil ich die Teilklasse erweitert habe.
Makotosan
2
Wenn Sie jedoch Typen aus einer bestimmten Baugruppe verwenden
möchten
26
Es verwirrt mich, dass ich auch 6 Jahre später durchschnittlich 50 Punkte pro Woche aus dieser Frage bekomme. Komm schon MS, behebe das. Geben Sie den Entwicklern zumindest ein Feedback, wenn dies schlecht läuft, anstatt sie auf eine leere Datei starren zu lassen.
Anderson Imes
1
9 Jahre später und du hilfst immer noch. Danke dir!
Parameter
38

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:

  • / t: code generiert den Code aus der angegebenen URL
  • / d: um das Verzeichnis für die Ausgabe anzugeben
  • / r: um eine Referenzbaugruppe anzugeben

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.

Blut
quelle
In meinem Fall kam dies zustande, nachdem ich auf eine Assembly verwiesen hatte, die auch auf meinen WCF-Dienst verwies. Entfernen dieser Baugruppe aus der Liste der Baugruppen, um Typen für die Freigabe freizugeben.
xr280xr
Beim Hinzufügen einer Dienstreferenz wurde eine bedeutungslose Fehlermeldung (nur ein Namespace) angezeigt, die auf das Problem hinwies.
Bcampolo
12

Überprüfen Sie in diesem Fall im Fehlerfenster und im Ausgabefenster, ob Fehlermeldungen vorliegen. Wenn dies nicht hilft, versuchen Sie es svcutil.exemanuell und prüfen Sie, ob Fehlermeldungen vorliegen.

John Saunders
quelle
@ Wie starte ich svcutil.exe? können Sie mir helfen ?
Arul Sidthan
@Arul: Verwenden Sie Google, um Informationen zu svcutil.exe zu finden.
John Saunders
2
Ich bin mir nicht sicher, ob Microsoft diesen Beitrag gelesen hat, aber nur ein Meldungsfeld mit den Fehlern und Warnungen, anstatt sie nur stillschweigend in das (in meinem Fall minimierte) Fehlerlistenfenster einzufügen, hätte es so gemacht, dass ich nicht auf Google musste Dies. Alternativ denke ich, wäre es nützlich, wenn die Registerkarte rot oder gelb angezeigt wird, wenn neue Warnungen / Fehler vorliegen.
jrh
12

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!

Matt Kane
quelle
5

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.

  1. Entfernen Sie die Servicereferenz mit Problemen.
  2. Klicken Sie im Projektmappen- Explorer auf den Projektnamen, um das Projekt hervorzuheben.
  3. Klicken Sie mit der rechten Maustaste auf die Projektreferenz.
  4. Klicken Sie oben in der Kontextliste auf das Element Bereinigen .
  5. Fügen Sie Ihre Servicereferenz wie gewohnt hinzu.

Hoffe das hilft.

user1353936
quelle
3

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.

Simon_Weaver
quelle
1
ok, es stellte sich heraus, dass ich auf eine alte Version von verwies System.Xml.Linq- also überprüfe die Versionen aller deiner DLLs, wenn du die Version
gewechselt
1

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.

Jon Person
quelle
1

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.

Joshua Lawrence
quelle
Das Auskommentieren aller Betriebsverträge hat für mich funktioniert. Ich habe die falschen Methoden als Schuldigen angesehen. Vielen Dank für den grundlegenden Ansatz zur Fehlerbehebung.
Fizch
1

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 .csDatei generiert , die ich in mein Projekt aufgenommen und zur Verwendung des Dienstes instanziiert habe.

Veverke
quelle
0

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:

  • Das 'IsReference'-Flag verursacht viele Probleme, aber das Entfernen ist nicht immer die Antwort (insbesondere: in Situationen mit Rekursion).
  • Das zugrunde liegende Problem ist, dass der Datenvertrag irgendwie nicht mit den Typnamen übereinstimmt, obwohl dies manchmal der Fall ist (huh? Ja, das haben Sie richtig gelesen!). Anscheinend ist der Serializer ziemlich wählerisch und es ist sehr schwer, das eigentliche Problem zu finden.
  • Das Entfernen der 'Referenzprüfungen' aus der 'Dienstreferenz konfigurieren' funktioniert, führt jedoch zu mehreren Implementierungen. Ich verwende jedoch häufig SOAP-Schnittstellen über DLLs hinweg wieder. In den meisten ausgereiften SOAs, die ich kenne, implementieren und erweitern mehrere Dienstschnittstellen dieselben Schnittstellenklassen. Das Entfernen der Überprüfungen für referenzierte Typen verwenden führt zu einer Situation, in der Sie Objekte nicht mehr einfach weitergeben können.

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:

  1. Erstellen Sie eine separate Schnittstellen-DLL. Schließen Sie in diese DLL alle DataContract- und ServiceContracts ein. Setzen Sie ServiceContracts auf Ihre Schnittstellen.
  2. Leiten Sie die Serverimplementierung von der Schnittstelle ab.
  3. 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:

  1. Sie umgehen den Prozess svcutil.exe, was bedeutet, dass Sie keine IsReference-Probleme haben
  2. DataContract-Typen und -Namen sind per Definition korrekt. Schließlich verwenden sowohl Server als auch Client dieselbe Definition.
  3. Wenn Sie die API erweitern oder Typen aus einer anderen DLL verwenden, gelten (1) und (2) weiterhin, sodass Sie dort keine Probleme haben.

Nachteile:

  1. A-Sync-Methoden sind ein Problem, da Sie keinen A-Sync-Proxy generieren. Daher würde ich dies in Silverlight-Anwendungen nicht empfehlen.
atlaste
quelle
0

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

Martype
quelle
0

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.

arif.khan.b
quelle
0

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.

Ziggler
quelle
0

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

Platedslicer
quelle
0

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.

INFOequipt
quelle
0

Folge diesen Schritten:

  1. Servicereferenz entfernen
  2. Schließen Sie Visual Studio
  3. Löschen Sie die Ordner / Bin und / Obj.
  4. Öffnen Sie Visual Studio.
  5. Fügen Sie die Servicereferenz hinzu.
  6. Bitte :)

Es scheint, dass beim Hinzufügen des Dienstes einige Verweise in diesen Ordnern verbleiben, die Fehler bei der automatischen Generierung von Code verursachen.

Exel Gamboa
quelle