Odpowiedzi:
Ogólnie uważam, że jest to problem z genem kodu i przez większość czasu jest to spowodowane konfliktem nazwy typu, którego nie można rozwiązać.
Jeśli klikniesz prawym przyciskiem myszy odniesienie do usługi, klikniesz konfiguruj i odznaczasz opcję „Ponowne użycie typów w zestawach, do których istnieją odniesienia” , prawdopodobnie rozwiąże to problem.
Jeśli korzystałeś z jakiegoś aspektu tej funkcji, być może będziesz musiał upewnić się, że twoje nazwy są wyczyszczone.
Jak wskazuje zaakceptowana odpowiedź, prawdopodobnie przyczyną jest problem z odniesieniem do typu podczas ponownego wykorzystywania typów. Zauważyłem, że kiedy nie możesz łatwo określić problemu, użycie wiersza poleceń svcutil.exe pomoże ci ujawnić podstawowy problem (jak wskazuje John Saunders).
Jako ulepszenie tutaj jest szybki przykład użycia svcutil.
svcutil /t:code https://secure.myserver.com/services/MyService.svc /d:test /r:"C:\MyCode\MyAssembly\bin\debug\MyAssembly.dll"
Gdzie:
Pełne odniesienie do wiersza poleceń svcutil tutaj: http://msdn.microsoft.com/en-us/library/aa347733.aspx
Po uruchomieniu svcutil powinieneś zobaczyć wyjątek zgłaszany przez import. Możesz otrzymać wiadomość tego typu dotyczącą jednego z Twoich typów: „typ, do którego się odwołujesz, nie może być użyty, ponieważ nie pasuje do zaimportowanego kontraktu DataContract”.
Może to być po prostu określone w tym, że istnieje różnica w jednym z typów w przywoływanym zestawie od tego, co zostało wygenerowane w DataContract dla usługi. W moim przypadku usługa, którą importowałem, miała nowsze, zaktualizowane typy z tego, co miałem w zestawie współdzielonym. Nie było to łatwo widoczne, ponieważ typ wymieniony w wyjątku wydawał się być ten sam. Jedyną różnicą był jeden z zagnieżdżonych typów złożonych używanych przez ten typ.
Istnieją inne, bardziej złożone scenariusze, które mogą wywołać tego typu wyjątek i wynikający z niego pusty plik reference.cs. Oto jeden przykład .
Jeśli masz ten problem i nie używasz typów ogólnych w kontraktach danych ani nie używasz IsReference = true, zalecam sprawdzenie, czy twoje udostępnione typy są dokładnie takie same na kliencie i serwerze. W przeciwnym razie prawdopodobnie napotkasz ten problem.
W takim przypadku spójrz w okno Błędy i okno Dane wyjściowe, aby sprawdzić, czy są jakieś komunikaty o błędach. Jeśli to nie pomoże, spróbuj uruchomić svcutil.exe
ręcznie i sprawdź, czy są jakieś komunikaty o błędach.
Przez cały dzień waliłem się w głowę z tym właśnie problemem. Właśnie to naprawiłem. Oto jak...
Usługa musiała działać przez SSL (tj. Jest pod adresem https://mydomain.com/MyService.svc )
Dodanie odwołania do usługi do usługi WCF na serwerze deweloperskim działało dobrze.
Wdrożenie dokładnie tej samej kompilacji usługi WCF na serwerze produkcyjnym na żywo, a następnie przełączenie się do aplikacji klienckiej i skonfigurowanie odwołania do usługi tak, aby wskazywało na usługę na żywo, nie wyświetlało żadnych błędów, ale aplikacja nie została zbudowana: Okazuje się, że odwołanie do usługi Plik Reference.cs był całkowicie pusty! Aktualizacja odniesienia do usługi nie spowodowała żadnej różnicy. Czyszczenie roztworu nie pomogło. Ponowne uruchomienie VS2010 nie zrobiło różnicy. Utworzenie nowego pustego rozwiązania, uruchomienie projektu konsoli i dodanie odwołania do usługi na żywo spowodowało dokładnie ten sam problem.
Nie sądziłem, że było to spowodowane konfliktami typów lub czymkolwiek, ale co do cholery - ponownie skonfigurowałem odwołanie do usługi WCF, odznaczając opcję „Ponowne użycie typów we wszystkich przywoływanych zestawach”. Brak przyjemności; Odłożyłem znacznik wyboru.
Następnym krokiem było wypróbowanie svcutil na referencyjnym adresie URL, aby sprawdzić, czy to pomoże wykryć problem. Oto polecenie:
svcutil /t:code https://mydomain.com/MyService.svc /d:D:\test
Dało to następujące efekty:
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.
To mnie całkowicie zaskoczyło. Pomimo intensywnego googlowania i stawania się naprawdę raczej zła, a także ponownego rozważenia kariery kierowcy autobusu, w końcu zastanowiłem się, dlaczego działało dobrze na pudełku rozwojowym. Czy może to być problem z konfiguracją usług IIS?
Zdalnie przeszedłem jednocześnie do wersji deweloperskiej i wersji na żywo i na każdym uruchomiłem Menedżera IIS (z uruchomionym IIS 7.5). Następnie przeszedłem przez wszystkie ustawienia konfiguracyjne w każdym pudełku, porównując wartości na każdym serwerze.
I tu jest problem: w sekcji „Ustawienia SSL” dla witryny upewnij się, że jest zaznaczona opcja „Wymagaj SSL” i zaznacz opcję „Zaakceptuj” przy opcji Certyfikaty klienta. Problem rozwiązany!
Zauważyłem, że zdarza się to często, gdy dodam odwołanie, usuwam je, a następnie ponownie dodam usługę o tej samej nazwie. Wydaje się, że konflikty typów są spowodowane pozostawieniem starych plików w miejscu, które program Visual Studio może nadal widzieć. Wszystko, co muszę zrobić, aby to naprawić, to wyczyścić przed dodaniem nowego odniesienia.
Mam nadzieję że to pomoże.
Miałem ten problem z Silverlight 5 zaktualizowanym z poprzedniej wersji.
Nawet ponowne dodanie odwołania do usługi nadal dawało mi pusty plik Reference.cs
Skończyło się na tym, że musiałem stworzyć zupełnie nowy projekt i odtworzyć odniesienie do usługi. Warto spróbować, jeśli poświęciłeś temu więcej niż pół godziny. Nawet jeśli jesteś zdeterminowany, aby naprawić oryginalny projekt, możesz spróbować tego tylko po to, aby zobaczyć, co się stanie, a następnie pracuj wstecz, aby spróbować rozwiązać problem.
Nigdy nie dowiedziałem się dokładnie, na czym polega problem - ale prawdopodobnie coś w pliku .csproj nie zostało zaktualizowane lub niektóre ustawienia poszły nie tak.
System.Xml.Linq
- więc sprawdź wersje wszystkich swoich bibliotek DLL, jeśli
Jeśli niedawno dodałeś kolekcję do projektu, gdy to zaczęło się pojawiać, problem może być spowodowany przez dwie kolekcje, które mają ten sam atrybut CollectionDataContract :
[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }
[CollectionDataContract(Name="AItems", ItemName="A")] // Wrong
public class CollectionB : List<B> { }
Naprawiłem błąd, przeglądając mój projekt i upewniając się, że wszystkie nazwy i pliki atrybut ItemName był unikalny:
[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }
[CollectionDataContract(Name="BItems", ItemName="B")] // Corrected
public class CollectionB : List<B> { }
Potem odświeżyłem referencje usługi i wszystko znowu działało.
Mój problem polegał na tym, że zostawiłem „ mex ” na końcu mojego łącza do usługi internetowej.
Zamiast „ http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc/mex ”
Użyj „ http://yeagertech.com/yeagerte/YeagerTechWcfService.YeagerTechWcfService.svc ”
Technika, która zadziałała w moim przypadku, po przeczytaniu tych odpowiedzi bezskutecznie, polegała po prostu na skomentowaniu całej mojej umowy i odkomentowaniu fragmentów, dopóki nie zadziała, w sposób binarny. To zawęża obraźliwy fragment kodu.
Następnie musisz tylko odgadnąć, co jest nie tak z tym kodem.
Oczywiście pomogłyby informacje o błędach w narzędziu.
Piszę umowę o świadczenie usług internetowych. Miałem zastępczą wyliczenie bez członków. W porządku. Ale jeśli użyję go we właściwości innej klasy i ponownie użyję biblioteki DLL kontraktu na kliencie, kodegen eksploduje bez komunikatu o błędzie. Uruchomienie svcutil.exe nie pomogło, po prostu nie udało się wyprowadzić pliku cs bez podania przyczyny.
Poniższe nie jest tutaj wymienione i było to rozwiązanie, które zastosowałem (SvcUtils był przydatny w zobaczeniu komunikatu o błędzie. Jednak błąd, który otrzymałem, był wrapper type message cannot be projected as a data contract type since it has multiple namespaces
. Znaczenie, podążyłem za tym tropem i dowiedziałem się o tymwsdl.exe
przez ten post).
W moim przypadku samo uruchomienie wsdl [ my-asmx-service-address ] wygenerowało bezproblemowy .cs
plik, który umieściłem w projekcie i uruchomiłem w celu użycia usługi.
Jak wskazuje @dblood, głównym problemem jest DataContractSerializer, który nie wykorzystuje poprawnie typów. Tutaj jest już kilka odpowiedzi, więc zacznę od dodania kilku zalet i wad:
Na szczęście, jeśli kontrolujesz swoje usługi, istnieje proste rozwiązanie, które rozwiązuje wszystkie te problemy. Oznacza to, że nadal możesz ponownie używać interfejsów usług we wszystkich bibliotekach DLL - co jest niezbędnym elementem IMO, aby uzyskać właściwe rozwiązanie. Oto jak działa rozwiązanie:
Użyj tej samej biblioteki DLL, aby skonstruować klienta przy użyciu swojej ulubionej metody. Na przykład (IMyInterface to interfejs umowy serwisowej):
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();
Innymi słowy: nie używaj funkcji „dodaj odwołanie do usługi” , ale wymuś programowi WCF używanie (poprawnych) typów usług, pomijając generowanie serwera proxy. W końcu masz już te zajęcia.
Profesjonaliści:
Cons:
Miałem również problem z uszkodzonymi referencjami usług podczas pracy z referencjami projektu po obu stronach (projekt usługi i projekt mający odniesienie do usługi). Jeśli na przykład plik .dll przywoływanego projektu nosi nazwę „Contoso.Development.Common”, ale nazwa projektu jest po prostu skrócona do „Wspólne”, również odwołania projektu do tego projektu są nazywane po prostu „Wspólne”. Usługa oczekuje jednak odwołania do „Contoso.Development.Common” w celu rozpoznania klas (jeśli ta opcja jest aktywowana w opcjach odwołania do usługi).
Tak więc w eksploratorze otworzyłem folder projektu, który odwołuje się do usługi i projektu „Common”. Tam edytuję plik projektu VS (.csproj) za pomocą notatnika. Wyszukaj nazwę referencyjnego projektu (w tym przykładzie jest to „Common.csproj”), a szybko znajdziesz wpis konfiguracji reprezentujący odniesienie do projektu.
Zmieniłam
<ProjectReference Include="..\Common\Common.csproj">
<Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project>
<Name>Common</Name>
</ProjectReference>
do
<ProjectReference Include="..\Common\Common.csproj">
<Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project>
<Name>Contoso.Development.Common</Name>
</ProjectReference>
Ważne jest, aby zmienić nazwę odwołania na nazwę biblioteki DLL, do której odwołuje się projekt.
Następnie przełącz się z powrotem na VS. Tam zostaniesz poproszony o ponowne załadowanie projektu, ponieważ został zmodyfikowany poza VS. Kliknij przycisk odświeżania.
Po wykonaniu tej czynności dodanie i zaktualizowanie odwołania do usługi działało zgodnie z oczekiwaniami.
Mam nadzieję, że to pomoże również komuś innemu.
Pozdrawiam MH
Z podobnym problemem spotkałem się wczoraj podczas tworzenia. Dowiedziałem się, że używam tej samej przestrzeni nazw w 2 różnych wersjach umów.
Mamy 2 wersje kontraktów, na przykład wersję 4 i wersję 5. Skopiowałem wszystkie kontrakty z wersji 4 i zmieniłem nazwę całej przestrzeni nazw z wersji 4 na wersję 5. Robiąc to zapomniałem zmienić nazwę przestrzeni nazw z v4 na v5 w jednym z plików. Z powodu konfliktu przestrzeni nazw plik Reference.cs był pusty.
Ten problem jest trudny do rozwiązania, ponieważ podczas generowania odwołania do usługi nie pojawia się żaden komunikat o błędzie. Aby zidentyfikować ten problem, ręcznie zweryfikowałem wszystkie nowo utworzone pliki. Istnieją inne sposoby rozwiązania tego problemu. Jest to pierwszy krok, który należy wykonać przed przejściem do innych opcji.
Podziękowania dla Johna Saundersa w poście powyżej, który dał mi pomysł, aby zajrzeć do okna błędów. Cały dzień pakowałem głowę i patrzyłem na okno wyjściowe pod kątem jakiegokolwiek błędu.
W moim przypadku winowajcą był ISerializable. Mam klasę DataContract z właściwością DataMember typu Exception. Nie można mieć elementu DataMember typu, który ma słowo kluczowe ISerializable. W tym wyjątku ISerializable, gdy tylko go usunąłem, wszystko działało jak urok.
Podczas próby rozwiązania tego problemu z svcutil
, otrzymałem błąd, o którym mowa w odpowiedzi dblood („nie można użyć przywoływanego typu, ponieważ nie pasuje do zaimportowanego kontraktu DataContract”).
W moim przypadku przyczyną źródłową wydawał się być typ wyliczeniowy, który miał atrybut DataContract, ale którego elementy członkowskie nie zostały oznaczone atrybutem EnumMember. Klasa problemusvcutil
miała właściwość z tym typem wyliczenia.
To lepiej by pasowało jako komentarz do odpowiedzi Dblooda, ale za mało reputacji za to ...
W moim przypadku miałem rozwiązanie z projektem VB Web Forms, które odwoływało się do C # UserControl. Zarówno projekt VB, jak i projekt CS miały odniesienie do usługi do tej samej usługi. Odniesienie pojawiło się w obszarze Referencje usług w projekcie VB oraz w grupie Connected Services w projekcie CS (framework).
Aby zaktualizować odniesienie do usługi (tj. Aby plik Reference.vb nie był pusty) w projekcie formularzy internetowych VB, musiałem USUNĄĆ PROJEKT CS, a następnie zaktualizować odwołanie do usługi VB, a następnie dodać projekt CS z powrotem do rozwiązanie.
Wykonaj następujące kroki:
Wygląda na to, że podczas dodawania usługi w tych folderach pozostają odniesienia, powodując błędy podczas automatycznego generowania kodu.