Às vezes, adicionar uma referência de serviço do WCF gera uma referência vazia.cs


159

Às vezes, adicionar uma referência de serviço do WCF gera um reference.cs vazio e não consigo fazer referência ao serviço em nenhum lugar do projeto.

Alguém já encontrou isso?

Respostas:


377

Geralmente acho que é um problema de geração de código e, na maioria das vezes, é porque eu tenho um conflito de nome de tipo que ele não conseguiu resolver.

Se você clicar com o botão direito do mouse na referência de serviço e clicar em configurar e desmarcar "Reutilizar tipos em assemblies referenciados" , provavelmente resolverá o problema.

Se você estava usando algum aspecto desse recurso, pode ser necessário garantir que seus nomes sejam limpos.


5
Quando aconteceu comigo, descobri que também precisava alterar o Tipo de coleção de ObjectModel.ObservableCollection para Generic.List
Yossi Dahan

2
Aconteceu comigo porque eu adicionei a aula parcial.
27512 Makotosan

2
No entanto, se você quisesse usar tipos de uma específica montagem, você pode selecionar apenas que a montagem e ele funciona muito bem (pelo menos no meu caso), ta
Dead.Rabit

26
Surpreende-me que recebo uma média de 50 pontos por semana desta pergunta, mesmo 6 anos depois. Vamos MS, conserte isso. Pelo menos, dê algum feedback aos desenvolvedores quando isso ocorrer mal, em vez de fazê-los olhar para um arquivo em branco.
Anderson Imes

1
9 anos depois e você ainda está ajudando. Obrigado!
parâmetro

38

Como aponta a resposta aceita, um problema de referência de tipo ao reutilizar tipos é provavelmente o culpado. Descobri que quando você não pode determinar facilmente o problema, o uso da linha de comando svcutil.exe ajudará a revelar o problema subjacente (como aponta John Saunders).

Como aprimoramento, aqui está um exemplo rápido do uso do svcutil.

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

Onde:

  • / t: code gera o código a partir de um determinado URL
  • / d: para especificar o diretório para a saída
  • / r: para especificar um assembly de referência

Referência completa da linha de comando svcutil aqui: http://msdn.microsoft.com/en-us/library/aa347733.aspx

Depois de executar o svcutil, você verá a exceção sendo lançada pela importação. Você pode receber este tipo de mensagem sobre um de seus tipos: "o tipo referenciado não pode ser usado, pois não corresponde ao DataContract importado".

Isso pode ser simplesmente o especificado, pois há uma diferença em um dos tipos no assembly referenciado do que foi gerado no DataContract para o serviço. No meu caso, o serviço que eu estava importando tinha tipos mais novos e atualizados do que eu tinha no assembly compartilhado. Isso não era prontamente aparente porque o tipo mencionado na exceção parecia ser o mesmo. O que foi diferente foi um dos tipos complexos aninhados usados ​​pelo tipo.

Existem outros cenários mais complexos que podem disparar esse tipo de exceção e o reference.cs em branco resultante. Aqui está um exemplo .

Se você estiver enfrentando esse problema e não estiver usando tipos genéricos em seus contratos de dados nem estiver usando IsReference = true, recomendo verificar se seus tipos compartilhados são exatamente iguais no seu cliente e servidor. Caso contrário, você provavelmente encontrará esse problema.


No meu caso, isso ocorreu depois que eu referenciei uma assembléia que também referenciou meu serviço WCF. Removendo esse assembly da lista de assemblies para compartilhar tipos com ele fixo.
Xr280xr 02/10

Eu estava recebendo uma mensagem de erro sem sentido (apenas um espaço para nome) ao adicionar uma Referência de Serviço e isso apontou o problema.
bcampolo

12

Quando isso acontecer, procure na janela Erros e na janela Saída para ver se há alguma mensagem de erro. Se isso não ajudar, tente executar svcutil.exemanualmente e verifique se há alguma mensagem de erro.


@ Como executar o svcutil.exe? pode me ajudar ?
Arul Sidthan

@Arul: Use o Google para encontrar informações sobre svcutil.exe.
21415 John Saunders

2
Não tenho certeza se a Microsoft leu esta postagem, mas apenas exibiu uma caixa de mensagem dizendo os erros e avisos em vez de apenas colocá-los silenciosamente na janela (minimizada, no meu caso) da Lista de erros, para que eu não precisasse usar o Google isto. Como alternativa, acho que seria útil exibir a guia em vermelho ou amarelo quando houver novos avisos / erros?
JRH

12

Venho batendo minha cabeça por um dia inteiro com esse problema exato. Eu apenas consertei. Aqui está como ...

O serviço teve que executar sobre SSL (ou seja, em https://mydomain.com/MyService.svc )

A adição de uma referência de serviço ao serviço WCF em um servidor de desenvolvimento funcionou bem.

A implantação exata da mesma compilação do serviço WCF no servidor de produção ao vivo, depois a mudança para o aplicativo cliente e a configuração da referência de serviço para apontar para o serviço ao vivo não apresentaram erros, mas o aplicativo não foi compilado: Acontece que a referência de serviço é O arquivo Reference.cs estava completamente vazio! A atualização da referência de serviço não fez diferença. Limpar a solução não ajudou. Reiniciar o VS2010 não fez diferença. Criar uma nova solução em branco, iniciar um projeto de console e adicionar uma referência de serviço ao serviço ativo exibiu exatamente o mesmo problema.

Eu não pensei que fosse devido a tipos conflitantes ou algo assim, mas que diabos - reconfigurei a referência de serviço do WCF desmarcando "Reutilizar tipos em todos os assemblies referenciados". Sem alegria; Coloquei a marca de volta.

O próximo passo foi tentar svcutil no URL de referência para ver se isso ajudaria a descobrir o problema. Aqui está o comando:

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

Isso produziu o seguinte:

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.

Isso me deixou completamente perplexo. Apesar de pesar bastante no Google, ficar bastante zangado e reconsiderar uma carreira como motorista de ônibus, finalmente considerei por que funcionava bem na caixa de desenvolvimento. Poderia ser um problema de configuração do IIS?

Eu remotei simultaneamente nas caixas live e de desenvolvimento e, em cada uma, iniciei o Gerenciador do IIS (executando o IIS 7.5). Em seguida, analisei cada configuração em cada caixa, comparando os valores em cada servidor.

E existe o problema: em "Configurações SSL" do site, verifique se "Requer SSL" está marcado e marque o botão de opção Certificados de cliente para "Aceitar". Problema resolvido!


5

Descobri que isso ocorre normalmente sempre que adiciono uma referência, a removo e, em seguida, adicione novamente um serviço com o mesmo nome. Os conflitos de tipo parecem ser causados ​​pelos arquivos antigos que permanecem em algum lugar que o Visual Studio ainda pode ver. Tudo o que preciso fazer para corrigi-lo é limpar antes de adicionar a nova referência.

  1. Remova a referência de serviço com problemas.
  2. Clique no nome do projeto no Solution Explorer para realçar o projeto.
  3. Clique com o botão direito do mouse na referência do projeto.
  4. Próximo ao topo da lista de contexto, clique no item Limpar .
  5. Adicione sua referência de serviço como faria normalmente.

Espero que isto ajude.


3

Eu tive esse problema com um Silverlight 5 atualizado a partir de uma versão anterior.

Mesmo a adição da referência de serviço ainda me dava um Reference.cs vazio

Acabei tendo que criar um novo projeto e recriar a referência de serviço. Isso é algo para tentar se você passou mais de meia hora nisso. Mesmo se você estiver determinado a corrigir o projeto original, tente isso apenas para ver o que acontece e, em seguida, trabalhe para trás para tentar corrigir o problema.

Eu nunca descobri exatamente qual era o problema - mas possivelmente algo no arquivo .csproj não foi atualizado ou alguma configuração deu errado.


1
ok acabou que eu estava fazendo referência a uma versão antiga do System.Xml.Linq- de modo a verificar as versões de todos os seus DLLs se você mudou versões
Simon_Weaver

1

Se você adicionou recentemente uma coleção ao seu projeto quando isso começou a ocorrer, o problema pode ser causado por duas coleções com o mesmo atributo CollectionDataContract :

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

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

Corrigi o erro varrendo meu projeto e garantindo que todos os atributos Name e ItemName fossem exclusivos:

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

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

Atualizei a referência de serviço e tudo funcionou novamente.



1

A técnica que funcionou para mim no meu caso, depois de ler essas respostas sem sucesso, era simplesmente comentar todo o meu contrato e remover os comentários até que não funcionasse mais, de forma binária. Isso restringe a parte ofensiva do código.

Então você só precisa adivinhar o que há de errado com esse código.

Algum feedback de erro na ferramenta teria ajudado, é claro.

Estou escrevendo um contrato de serviço da web. Eu tinha um enum de espaço reservado sem membros. Isso está ok. Mas se eu usá-lo em uma propriedade de outra classe e reutilizar a DLL do contrato no cliente, o codegen explode sem nenhuma mensagem de erro. A execução de svcutil.exe não ajudou, apenas falhou ao gerar um arquivo cs sem mencionar o motivo.


Comentar todos os contratos de operação funcionou para mim. Eu estava olhando os métodos errados como o culpado. Obrigado pela abordagem de volta ao básico para solução de problemas.
fizch

1

O seguinte não está listado aqui e foi a solução que eu adotei (SvcUtils foi útil para ver a mensagem de erro. No entanto, o erro que recebi foi wrapper type message cannot be projected as a data contract type since it has multiple namespaces . Significado, eu segui essa liderança, e aprendeu sobre wsdl.exevia este post).

No meu caso, simplesmente executar wsdl [ meu-asmx-service-address ] gerou um .csarquivo sem problemas , que eu incluí no meu projeto e instantei a usar o serviço.


0

Como o @dblood aponta, o principal problema está no DataContractSerializer, que não reutiliza corretamente os tipos. Já existem algumas respostas aqui, então vou começar adicionando alguns prós e contras sobre estes:

  • O sinalizador 'IsReference' causa muitos problemas, mas a remoção nem sempre é a resposta (especificamente: em situações com recursão).
  • A questão subjacente é que o contrato de dados não é o mesmo que os nomes dos tipos, mesmo que algumas vezes sejam (huh? Sim, você leu certo!). Aparentemente, o serializador é bastante exigente e é muito difícil encontrar o problema real.
  • A remoção das 'verificações de referências' das 'Configurar referência de serviço' funciona, mas deixa você com várias implementações. No entanto, muitas vezes reutilizo interfaces SOAP entre DLLs. Além disso, na maioria das SOA maduras que eu conheço, várias interfaces de serviços implementam e estendem as mesmas classes de interface. A remoção das verificações "usar tipos referenciados" resulta em uma situação em que você não pode mais simplesmente passar objetos.

Felizmente, se você estiver no controle de seu serviço, existe uma solução simples que resolve todos esses problemas. Isso significa que você ainda pode reutilizar as interfaces de serviço nas DLLs, o que é essencial para uma solução adequada. É assim que a solução funciona:

  1. Crie uma DLL de interface separada. Nessa DLL, inclua todos os DataContract e ServiceContract; coloque ServiceContract em suas interfaces.
  2. Derive a implementação do servidor da interface.
  3. Use a mesma DLL para construir o cliente usando seu método favorito. Por exemplo (IMyInterface é a interface do contrato de serviço):

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

Em outras palavras: não use a funcionalidade 'adicionar referência de serviço' , mas force o WCF a usar os tipos de serviço (corretos) ignorando a geração de proxy. Afinal, você já tem essas classes.

Profissionais:

  1. Você ignora o processo svcutil.exe, o que significa que você não tem nenhum problema de IsReference
  2. Os tipos e nomes do DataContract estão corretos por definição; afinal, servidor e cliente usam a mesma definição.
  3. Se você estender a API ou usar tipos de outra DLL, (1) e (2) ainda serão mantidos, para que você não tenha problemas.

Contras:

  1. Os métodos A-sync são um problema, pois você não gera um proxy a-sync. Como resultado, eu não recomendaria isso nos aplicativos Silverlight.

0

Eu também tive o problema de referências de serviço quebradas ao trabalhar com referências de projeto de ambos os lados (o projeto de serviço e o projeto tendo uma referência ao serviço). Se o arquivo .dll do projeto mencionado, por exemplo, for chamado "Contoso.Development.Common", mas o nome do projeto for simplesmente abreviado para "Comum", também as referências a esse projeto serão nomeadas apenas "Comum". No entanto, o serviço espera uma referência a "Contoso.Development.Common" para resolver classes (se essa opção estiver ativada nas opções de referência de serviço).

Assim, com o explorer, abri a pasta do projeto que faz referência ao serviço e ao projeto "Comum". Lá editei o arquivo de projeto do VS (.csproj) com o bloco de notas. Procure o nome do projeto referenciado (que é "Common.csproj" neste exemplo) e você encontrará rapidamente a entrada de configuração que representa a referência do projeto.

eu mudei

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

para

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

O importante é alterar o nome da referência para o nome da dll que o projeto referenciado possui como saída.

Em seguida, volte para o VS. Lá, você será solicitado a recarregar o projeto, pois ele foi modificado fora do VS. Clique no botão recarregar.

Depois de adicionar e atualizar, a referência de serviço funcionou conforme o esperado.

Espero que isso também ajude outra pessoa.

Atenciosamente MH


0

Eu enfrentei um problema semelhante ontem durante o desenvolvimento. Descobri que estava usando o mesmo espaço para nome em duas versões diferentes de contratos.

Temos duas versões de contratos, por exemplo, versão4 e versão5. Copiei todos os contratos da versão4 e renomeei todo o namespace da versão4 para a versão5. Ao fazer isso, esqueci de renomear o espaço para nome da v4 para a v5 em um dos arquivos. Devido ao conflito de espaço para nome, o arquivo Reference.cs estava vazio.

É difícil solucionar esse problema, pois você não recebe nenhuma mensagem de erro ao gerar a referência de serviço. Para identificar esse problema, validaria manualmente todos os novos arquivos criados. Existem outras maneiras de resolver esse problema. Este é o primeiro passo que você deve executar antes de procurar outras opções.


0

Agradeço ao post de John Saunders acima, que me deu uma idéia para olhar na janela de erro. Eu estava ensacando o dia inteiro minha cabeça e estava olhando para a janela Saída por algum erro.

No meu caso, o culpado era irresistível. Eu tenho uma classe DataContract com a propriedade DataMember do tipo Exception. Você não pode ter nenhum DataMember do tipo com a palavra-chave ISerializable. Nesta exceção ISerializable assim que eu removi tudo funcionou como um encanto.


0

Ao tentar solucionar esse problema com svcutil , recebi o erro mencionado na resposta do dblood ("o tipo referenciado não pode ser usado, pois não corresponde ao DataContract importado").

No meu caso, a causa subjacente parecia ser um tipo de enum que tinha o atributo DataContract, mas cujos membros não foram marcados com o atributo EnumMember. A classe do problemasvcutil apontada tinha uma propriedade com esse tipo de enumeração.

Isso se encaixaria melhor como um comentário à resposta do dblood, mas não o suficiente para isso ...


0

No meu caso, eu tinha uma solução com o projeto VB Web Forms que referenciava um C # UserControl. Tanto o projeto VB quanto o projeto CS tinham uma referência de serviço para o mesmo serviço. A referência apareceu em Referências de serviço no projeto VB e no agrupamento Connected Services no projeto CS (estrutura).

Para atualizar a referência de serviço (ou seja, fazer com que o arquivo Reference.vb não fique vazio) no projeto de formulários da web do VB, eu precisava REMOVER O PROJETO CS, atualizar a referência de serviço do VB e adicionar o projeto CS novamente ao projeto a solução.


0

Siga esses passos:

  1. Remover referência de serviço
  2. Feche o Visual Studio
  3. Excluir / Bin e / Obj pastas.
  4. Abra o Visual Studio.
  5. Adicione a referência de serviço.
  6. De nada :)

Parece que algumas referências são deixadas nessas pastas ao adicionar o serviço, causando erros durante a geração automática de código.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.