A volte l'aggiunta di un riferimento al servizio WCF genera un riferimento.cs vuoto


159

A volte l'aggiunta di un riferimento al servizio WCF genera un riferimento vuoto e non posso fare riferimento al servizio in nessun punto del progetto.

Qualcuno ha riscontrato questo?

Risposte:


377

Generalmente scopro che si tratta di un problema di code-gen e la maggior parte delle volte è perché ho un conflitto di nomi di tipo che non è riuscito a risolvere.

Se fai clic con il pulsante destro del mouse sul riferimento del servizio e fai clic su configura e deseleziona "Riutilizza i tipi negli assiemi di riferimento" , probabilmente risolverà il problema.

Se stavi utilizzando alcuni aspetti di questa funzione, potresti aver bisogno di assicurarti che i tuoi nomi siano stati ripuliti.


5
Quando mi è successo, ho scoperto che dovevo anche cambiare il tipo di raccolta da ObjectModel.ObservableCollection a Generic.List
Yossi Dahan,

2
Mi è successo perché ho aggiunto alla classe parziale.
Makotosan,

2
Tuttavia, se si desidera utilizzare i tipi da un assembly specifico, è possibile selezionare solo
quell'assembly

26
Mi sorprende il fatto che ottengo una media di 50 punti a settimana da questa domanda anche 6 anni dopo. Forza MS, aggiusta questo. Almeno dai agli sviluppatori un feedback quando questo va male invece di farli fissare un file vuoto.
Anderson Imes,

1
9 anni dopo e stai ancora aiutando. Grazie!
parametro

38

Come sottolinea la risposta accettata, un colpevole di riferimento del tipo quando si riutilizzano i tipi è probabilmente il colpevole. Ho scoperto che quando non riesci a determinare facilmente il problema, l'utilizzo della riga di comando svcutil.exe ti aiuterà a rivelare il problema sottostante (come sottolinea John Saunders).

Come miglioramento ecco un rapido esempio dell'uso di svcutil.

svcutil /t:code https://secure.myserver.com/services/MyService.svc /d:test /r:"C:\MyCode\MyAssembly\bin\debug\MyAssembly.dll"

Dove:

  • / t: il codice genera il codice dall'URL specificato
  • / d: per specificare la directory per l'output
  • / r: per specificare un assembly di riferimento

Riferimento completo della riga di comando svcutil qui: http://msdn.microsoft.com/en-us/library/aa347733.aspx

Una volta eseguito svcutil, dovresti vedere l'eccezione generata dall'importazione. Potresti ricevere questo tipo di messaggio relativo a uno dei tuoi tipi: "il tipo di riferimento non può essere utilizzato poiché non corrisponde a DataContract importato".

Ciò potrebbe essere semplicemente quello specificato in quanto esiste una differenza in uno dei tipi nell'assieme di riferimento da ciò che è stato generato in DataContract per il servizio. Nel mio caso, il servizio che stavo importando aveva tipi più recenti e aggiornati rispetto a quelli che avevo nell'assembly condiviso. Ciò non era immediatamente evidente perché il tipo menzionato nell'eccezione sembrava essere lo stesso. Ciò che era diverso era uno dei tipi complessi nidificati utilizzati dal tipo.

Esistono altri scenari più complessi che possono attivare questo tipo di eccezione e risultante riferimento.cs vuoto. Ecco un esempio .

Se si verifica questo problema e non si utilizzano tipi generici nei contratti di dati né si utilizza IsReference = true, si consiglia di verificare con certezza che i tipi condivisi siano esattamente gli stessi sul client e sul server. Altrimenti, probabilmente incontrerai questo problema.


Nel mio caso, ciò è avvenuto dopo che ho fatto riferimento a un assembly che faceva riferimento anche al mio servizio WCF. Rimozione di quell'assieme dall'elenco degli assiemi per condividerne i tipi con correzione.
xr280xr,

Stavo ricevendo un messaggio di errore insignificante (solo uno spazio dei nomi) quando ho aggiunto un riferimento al servizio e questo ha sottolineato il problema.
bcampolo,

12

Quando ciò accade, guarda nella finestra Errori e nella finestra Output per vedere se ci sono messaggi di errore. Se il problema persiste, prova a eseguire svcutil.exemanualmente e verifica se sono presenti messaggi di errore.


@ Come eseguire svcutil.exe? Mi potete aiutare ?
Arul Sidthan,

@Arul: utilizzare Google per trovare informazioni su svcutil.exe.
John Saunders,

2
Non sono sicuro che Microsoft abbia letto questo post ma anche solo mostrando una finestra di messaggio che dice gli errori e gli avvisi invece di metterli in silenzio nella finestra (minimizzata, nel mio caso) dell'elenco degli errori lo avrebbe reso quindi non avevo bisogno di Google Questo. In alternativa, suppongo che sarebbe utile visualizzare la scheda in rosso o giallo in presenza di nuovi avvisi / errori?
jrh

12

Ho battuto la testa per un giorno intero con questo esatto problema. L'ho appena risolto. Ecco come...

Il servizio doveva essere eseguito su SSL (ovvero su https://mydomain.com/MyService.svc )

L'aggiunta di un riferimento al servizio WCF su un server di sviluppo ha funzionato perfettamente.

Distribuzione del esatto stessa build del servizio WCF sul server di produzione dal vivo, per poi passare a l'applicazione client e la configurazione del riferimento al servizio al punto al servizio dal vivo visualizzato alcun errore, ma l'applicazione non avrebbero costruito: Si scopre che i di riferimento del servizio Il file Reference.cs era completamente vuoto! L'aggiornamento del riferimento del servizio non ha fatto alcuna differenza. La pulizia della soluzione non ha aiutato. Il riavvio di VS2010 non ha fatto differenza. La creazione di una nuova soluzione vuota, l'avvio di un progetto console e l'aggiunta di un riferimento di servizio al servizio live hanno mostrato esattamente lo stesso problema.

Non pensavo che fosse dovuto a tipi in conflitto o altro, ma che diamine - ho riconfigurato il riferimento al servizio WCF deselezionando "Riutilizza i tipi in tutti gli assembly referenziati". Nessuna gioia; Metto il segno di spunta.

Il passo successivo è stato provare svcutil sull'URL di riferimento per vedere se ciò avrebbe aiutato a scoprire il problema. Ecco il comando:

svcutil /t:code https://mydomain.com/MyService.svc /d:D:\test

Ciò ha prodotto quanto segue:

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.

Questo mi ha lasciato completamente perplesso. Nonostante abbia cercato pesantemente su google e ottenuto piuttosto cross, e riconsiderando la carriera di autista di autobus, ho finalmente considerato il motivo per cui ha funzionato bene sulla scatola di sviluppo. Potrebbe essere un problema di configurazione IIS?

Ho remotato simultaneamente sia nello sviluppo che nei live box, e su ciascuno ho avviato IIS Manager (eseguendo IIS 7.5). Successivamente, ho esaminato tutte le impostazioni di configurazione su ciascuna casella, confrontando i valori su ciascun server.

E c'è il problema: in "Impostazioni SSL" per il sito, assicurati che "Richiedi SSL" sia selezionato e controlla il pulsante di opzione Certificati client per "Accetta". Problema risolto!


5

Ho riscontrato che ciò si verifica comunemente ogni volta che aggiungo un riferimento, lo rimuovo e quindi aggiungo nuovamente un servizio con lo stesso nome. I conflitti di tipo sembrano essere causati dai vecchi file che rimangono in qualche punto che Visual Studio può ancora vedere. Tutto quello che devo fare per risolverlo, è pulito prima di aggiungere il nuovo riferimento.

  1. Rimuovere il riferimento al servizio che presenta problemi.
  2. Fare clic sul nome del progetto in Esplora soluzioni per evidenziare il progetto.
  3. Fare clic con il tasto destro del mouse sul riferimento del progetto.
  4. Nella parte superiore dell'elenco di contesto, fai clic sull'elemento Pulisci .
  5. Aggiungi il riferimento al servizio come faresti normalmente.

Spero che questo ti aiuti.


3

Ho avuto questo problema con un Silverlight 5 aggiornato da una versione precedente.

Anche aggiungere nuovamente il riferimento al servizio mi ha dato un riferimento vuoto

Ho finito per dover creare un nuovo progetto e ricreare il riferimento al servizio. Questo è qualcosa da provare se hai trascorso più di mezz'ora su questo. Anche se sei determinato a risolvere il progetto originale, potresti provare questo solo per vedere cosa succede e quindi lavorare all'indietro per provare a risolvere il problema.

Non ho mai capito esattamente quale fosse il problema, ma probabilmente qualcosa nel file .csproj non è stato aggiornato o alcune impostazioni sono andate male.


1
ok si è scoperto che mi System.Xml.Linq
riferivo a

1

Se hai recentemente aggiunto una raccolta al tuo progetto quando è iniziato, il problema potrebbe essere causato da due raccolte che hanno lo stesso attributo CollectionDataContract :

[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }

[CollectionDataContract(Name="AItems", ItemName="A")]  // Wrong
public class CollectionB : List<B> { }

Ho corretto l'errore scorrendo il mio progetto e assicurandomi che ogni attributo Name e ItemName fosse univoco:

[CollectionDataContract(Name="AItems", ItemName="A")]
public class CollectionA : List<A> { }

[CollectionDataContract(Name="BItems", ItemName="B")]  // Corrected
public class CollectionB : List<B> { }

Quindi ho aggiornato il riferimento al servizio e tutto ha funzionato di nuovo.



1

La tecnica che ha funzionato per me nel mio caso, dopo aver letto queste risposte senza successo, è stata semplicemente quella di commentare tutto il mio contratto e i frammenti di commento fino a quando non funziona più, in modo binario. Ciò restringe il bit di codice offensivo.

Quindi devi solo indovinare cosa c'è che non va in quel codice.

Alcuni feedback sugli errori nello strumento avrebbero ovviamente aiutato.

Sto scrivendo un contratto di servizio web. Ho avuto un enum segnaposto senza membri. Va bene. Ma se lo uso in una proprietà di un'altra classe e riutilizzo il contratto dll sul client, il codegen esplode senza alcun messaggio di errore. L'esecuzione di svcutil.exe non ha aiutato, non è riuscito a produrre un file cs senza menzionarne il motivo.


Commentare tutti i contratti operativi ha funzionato per me. Stavo guardando i metodi sbagliati come colpevole. Grazie per l'approccio alla base per la risoluzione dei problemi.
Fizch,

1

Quanto segue non è elencato qui, ed è stata la soluzione che ho adottato (SvcUtils è stato utile nel vedere il messaggio di errore. Tuttavia, l'errore che ho ricevuto è stato wrapper type message cannot be projected as a data contract type since it has multiple namespaces. Significato, ho seguito questo esempio e ho appreso wsdl.exetramite questo post).

Nel mio caso, semplicemente eseguendo wsdl [ my-asmx-service-address ] ha generato un .csfile senza problemi , che ho incluso nel mio progetto e ho istanziato per usare il servizio.


0

Come sottolinea @dblood, il problema principale è nel DataContractSerializer, che non riutilizza correttamente i tipi. Ci sono già alcune risposte qui, quindi inizierò aggiungendo alcuni pro e contro su questi:

  • Il flag 'IsReference' causa molti problemi, ma rimuoverlo non è sempre la risposta (in particolare: in situazioni con ricorsione).
  • Il problema di fondo è che il contratto dati non è in qualche modo uguale ai nomi dei tipi, anche se a volte lo sono (eh? Sì, hai letto bene!). Apparentemente il serializzatore è piuttosto esigente ed è molto difficile trovare il vero problema.
  • La rimozione dei "controlli dei riferimenti" dal "Configura riferimento al servizio" funziona, ma ti lascia con implementazioni multiple. Tuttavia, riutilizzo spesso le interfacce SOAP nelle DLL. Inoltre, nella maggior parte delle SOA mature che conosco, più interfacce di servizi implementano ed estendono le stesse classi di interfaccia. La rimozione dei controlli "usa tipi di riferimento" provoca una situazione in cui non è più possibile semplicemente passare oggetti in giro.

Fortunatamente, se hai il controllo del tuo servizio, esiste una soluzione semplice che risolve tutti questi problemi. Ciò significa che è ancora possibile riutilizzare le interfacce di servizio tra le DLL, che è l'IMO un must per una soluzione adeguata. Ecco come funziona la soluzione:

  1. Creare una DLL di interfaccia separata. In quella DLL, includere tutti i DataContract e ServiceContract; metti ServiceContract nelle tue interfacce.
  2. Deriva l'implementazione del server dall'interfaccia.
  3. Utilizzare la stessa DLL per costruire il client utilizzando il metodo preferito. Ad esempio (IMyInterface è l'interfaccia del contratto di servizio):

    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();

In altre parole: non utilizzare la funzionalità "Aggiungi riferimento al servizio" , ma forzare WCF a utilizzare i tipi di servizio (corretti) ignorando la generazione del proxy. Dopo tutto, hai già queste lezioni.

Professionisti:

  1. Si ignora il processo svcutil.exe, il che significa che non si hanno problemi con IsReference
  2. I tipi e i nomi di DataContract sono corretti per definizione; dopo tutto, sia il server che il client usano la stessa definizione.
  3. Se estendi l'API o usi tipi da un'altra DLL, (1) e (2) restano comunque validi, quindi non avrai problemi.

Contro:

  1. I metodi A-sync sono una seccatura, poiché non si genera un proxy a-sync. Di conseguenza, non consiglierei di farlo nelle applicazioni Silverlight.

0

Ho anche avuto il problema dei riferimenti di servizio non funzionanti quando lavoravo con riferimenti di progetto su entrambi i lati (il progetto di servizio e il progetto avevano un riferimento al servizio). Se, ad esempio, il file DLL del progetto a cui viene fatto riferimento si chiama "Contoso.Development.Common", ma il nome del progetto viene semplicemente abbreviato in "Comune", anche i riferimenti di progetto a questo progetto vengono chiamati semplicemente "Comune". Tuttavia, il servizio prevede un riferimento a "Contoso.Development.Common" per la risoluzione delle classi (se questa opzione è attivata nelle opzioni di riferimento del servizio).

Quindi con explorer ho aperto la cartella del progetto che fa riferimento al servizio e al progetto "Comune". Lì ho modificato il file di progetto VS (.csproj) con il blocco note. Cerca il nome del progetto referenziato (in questo esempio "Common.csproj") e troverai rapidamente la voce di configurazione che rappresenta il riferimento al progetto.

Ho cambiato

<ProjectReference Include="..\Common\Common.csproj"> <Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project> <Name>Common</Name> </ProjectReference>

per

<ProjectReference Include="..\Common\Common.csproj"> <Project>{C90AAD45-6857-4F83-BD1D-4772ED50D44C}</Project> <Name>Contoso.Development.Common</Name> </ProjectReference>

L'importante è cambiare il nome del riferimento con il nome della dll che il progetto referenziato ha come output.

Quindi tornare a VS. Lì ti verrà chiesto di ricaricare il progetto poiché è stato modificato al di fuori di VS. Fai clic sul pulsante Ricarica.

Dopo aver fatto ciò aggiungendo e aggiornando il riferimento al servizio ha funzionato esattamente come previsto.

Spero che questo aiuti anche qualcun altro.

Saluti MH


0

Ho affrontato un problema simile ieri durante lo sviluppo. Ho scoperto che stavo usando lo stesso spazio dei nomi in 2 diverse versioni di contratti.

Abbiamo 2 versioni di contratti, ad esempio versione 4 e versione5. Ho copiato tutti i contratti dalla versione 4 e rinominato tutto lo spazio dei nomi dalla versione 4 alla versione 5. Nel fare ciò, ho dimenticato di rinominare lo spazio dei nomi da v4 a v5 in uno dei file. A causa di un conflitto nello spazio dei nomi, il file Reference.cs era vuoto.

Questo problema è difficile da risolvere poiché non viene visualizzato alcun messaggio di errore durante la generazione del riferimento del servizio. Per identificare questo problema avrei convalidato manualmente tutti i nuovi file che avevo creato. Esistono altri modi per risolvere questo problema. Questo è il primo passo che dovresti eseguire prima di scegliere altre opzioni.


0

Grazie al post di John Saunders sopra che mi ha dato l'idea di guardare nella finestra Errore. Mi stavo insaccando tutto il giorno e stavo guardando la finestra Output per eventuali errori.

Nel mio caso il colpevole era ISerializable. Ho una classe DataContract con proprietà DataMember di tipo Exception. Non è possibile avere alcun DataMember di tipo con una parola chiave ISerializable. In questa eccezione è ISerializable non appena l'ho rimosso tutto ha funzionato come un fascino.


0

Durante il tentativo di risolvere questo problema svcutil, ho ricevuto l'errore indicato nella risposta di dblood ("il tipo di riferimento non può essere utilizzato poiché non corrisponde a DataContract importato").

Nel mio caso la causa sottostante sembrava essere un tipo enum che aveva l'attributo DataContract, ma i cui membri non erano contrassegnati con l'attributo EnumMember. La classe del problema svcutilindicata aveva una proprietà con quel tipo di enum.

Ciò si adatterebbe meglio come commento alla risposta di Dblood, ma non abbastanza rappresentante per quello ...


0

Nel mio caso avevo una soluzione con il progetto VB Web Forms che faceva riferimento a UserControl C #. Sia il progetto VB che il progetto CS avevano un riferimento di servizio allo stesso servizio. Il riferimento è apparso in Riferimenti di servizio nel progetto VB e nel gruppo Servizi connessi nel progetto CS (framework).

Per aggiornare il riferimento del servizio (ovvero ottenere che il file Reference.vb non sia vuoto) nel progetto di moduli Web VB, dovevo RIMUOVERE IL PROGETTO CS, quindi aggiornare il riferimento del servizio VB, quindi aggiungere nuovamente il progetto CS in la soluzione.


0

Segui questi passi:

  1. Rimuovi riferimento al servizio
  2. Chiudi Visual Studio
  3. Elimina le cartelle / Bin e / Obj.
  4. Apri Visual Studio.
  5. Aggiungi il riferimento al servizio.
  6. Prego :)

Sembra che alcuni riferimenti rimangano in queste cartelle quando si aggiunge il servizio, causando errori durante la generazione automatica del codice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.