Não foi possível encontrar o elemento do terminal padrão

370

Adicionei um proxy a um serviço da web em uma solução do VS2008 / .NET 3.5. Ao construir o cliente .NET lança este erro:

Não foi possível encontrar o elemento do terminal padrão que referencia o contrato 'IMySOAPWebService' na seção de configuração do cliente ServiceModel. Isso pode ocorrer porque nenhum arquivo de configuração foi encontrado para o seu aplicativo ou porque nenhum elemento do terminal correspondente a este contrato foi encontrado no elemento do cliente.

A procura desse erro me diz para usar o espaço para nome completo no contrato. Aqui está o meu app.config com espaço para nome completo:

<client>
  <endpoint address="http://192.168.100.87:7001/soap/IMySOAPWebService"
            binding="basicHttpBinding" bindingConfiguration="IMySOAPWebServicebinding"
            contract="Fusion.DataExchange.Workflows.IMySOAPWebService" name="IMySOAPWebServicePort" />
</client>

Estou executando o XP local (mencionei isso porque vários hits do Google mencionam win2k3) O app.config é copiado para app.exe.config, de modo que também não é o problema.

Alguma pista?

edosoft
fonte
Se isso estiver sendo executado em um servidor Web, você precisará adicionar .svc. Exemplo: " 192.168.100.87:7001/soap/IMySOAPWebService.svc
Darren C
O serviço não é um serviço .NET, não está sendo executado em um servidor da Web.
9788 edosoft
Resolvi esse problema em projetos desenvolvidos em .NET, mas tenho alguns projetos em VB6 e tenho o mesmo problema. Alguma ideia?
Gabriel Intriago

Respostas:

588

"Este erro pode ocorrer se você estiver chamando o serviço em uma biblioteca de classes e chamando a biblioteca de classes de outro projeto."

Nesse caso, você precisará incluir as definições de configuração do WS nos principais projetos app.config se for um winapp ou web.config se for um aplicativo web. Este é o caminho a seguir, mesmo com PRISM e WPF / Silverlight.

LR
fonte
11
Essa não foi a causa do meu problema específico, mas tenho certeza de que isso ajudará outras pessoas. Obrigado
edosoft
9
Existe alguma maneira de mesclar automaticamente os dois? E se a biblioteca de classes atualizar sua configuração? Você acabou de se lembrar de atualizar as informações de configuração copiadas em todos os projetos que fazem referência a ela? Essa correção parece confiar demasiado na vigilância do colaborador ...
Sean Hanley
11
Estou recebendo o mesmo erro para um aplicativo WP7 (acredito que o Silverlight) e demorei muito para perceber que ServiceReferences.ClientConfigé gerado no diretório do projeto. Copiar os elementos <bindings>e <client>do arquivo da minha biblioteca para o meu aplicativo principal (que antes estavam vazios) fazia as coisas funcionarem.
DavidMalon #
4
A razão pela qual isso acontece (como eu o entendo) é que os valores de configuração são lidos no projeto principal em uma solução, seja web, winforms, wpf etc. Digamos, por exemplo, que você tenha um projeto de biblioteca de classes para acessar um banco de dados, a entrada connectionString precisará estar na configuração principal do projeto, e não na configuração da biblioteca de classes.
Ciaran Bruen
6
Portanto, podemos concluir que, se usarmos o WCF em uma biblioteca, seria melhor codificar as configurações diretamente como o link stackoverflow.com/questions/7688798/… mostrado.
Youngjae
90

Resolvi isso (acho que, como outros sugeriram), criando as instâncias de endereço de endpoint e de ligação - porque não queria adicionar novas configurações aos arquivos de configuração (isso substitui algum código de biblioteca existente usado amplamente, e usei anteriormente uma referência de serviço da Web mais antiga etc.) e, portanto, eu queria poder incluir isso sem precisar adicionar novas configurações em todos os lugares.

var remoteAddress = new System.ServiceModel.EndpointAddress(_webServiceUrl);

using (var productService = new ProductClient(new System.ServiceModel.BasicHttpBinding(), remoteAddress))
{
    //set timeout
    productService.Endpoint.Binding.SendTimeout = new TimeSpan(0,0,0,_webServiceTimeout);

    //call web service method
    productResponse = productService.GetProducts();
} 

Editar

Se você estiver usando https, precisará usar em BasicHttpsBindingvez de BasicHttpBinding.

Tom Haigh
fonte
11
Esta é uma resposta útil. Em um serviço da Web que estou usando, o ponto de extremidade personalizado precisava ser vinculado na declaração inicial do objeto. Não funcionaria se eu tentasse fazer isso mais tarde.
Paul Morel
2
Por mais que eu suspeite que a resposta principal possa ter funcionado também, sua solução funcionou e me parece preferível invadir meus próprios arquivos de configuração.
Sam I am diz Reinstate Monica
Funciona um encanto! Eu prefiro poder definir o ponto de extremidade no código, em vez de distribuir um arquivo "app.config" com o meu aplicativo.
Daniel Gee
11
Se é um serviço web Https lembrar de mudar BasicHttpBinding () para BasicHttpsBinding ()
Anthony
Esta solução é melhor para aplicativos como o EXCEL-DNA, que não possui app.config ou web.config.
User781700
75

Tendo testado várias opções, finalmente resolvi isso usando

contract = "IMySOAPWebService"

ou seja, sem o espaço para nome completo na configuração. Por alguma razão, o nome completo não foi resolvido corretamente

edosoft
fonte
3
Parece que o nome do contrato deve ser escrito exatamente da mesma maneira que o cliente. No meu caso, eu tinha var proxy = new ExternalServices.ServiceClient("MyServiceEndpoint");Trabalhou quando a I acrescentou o namespace de contrato:contract="ExternalServices.IMyService"
Anatoly Mironov
Isso não funcionou para mim. Meu problema pode ser um pouco diferente. Recebo esse erro de tempos em tempos, nem sempre. Qual pode ser o problema? Erro poderia estar no lado do serviço? _Obrigado
albatross
57

Eu tive esse mesmo problema. Acontece que, para uma referência na web, você deve fornecer a URL como o primeiro parâmetro para o construtor:

new WebService.WebServiceSoapClient("http://myservice.com/moo.aspx");

Para um novo estilo de REFERÊNCIA DE SERVIÇO Web, você deve fornecer um nome que se refira a uma entrada de terminal na configuração:

new WebService.WebServiceSoapClient("WebServiceEndpoint");

Com uma entrada correspondente em Web.configou App.config:

<client>
      <endpoint address="http://myservice.com/moo.aspx"
        binding="basicHttpBinding" 
        bindingConfiguration="WebService"
        contract="WebService.WebServiceSoap"
        name="WebServiceEndpoint" />
    </client>
  </system.serviceModel>

Muito difícil remover a visão do túnel sobre "funcionou em um programa mais antigo" ...

Andomar
fonte
3
Ah ha! Isso foi corrigido para mim, eu estava apenas usando um construtor vazio antes, que continuava falhando: new WebService.WebServiceSoapClient (); // falha
travis
Esta solução funcionou !!! mas estou realmente curioso para saber por que o ponto final padrão não foi carregado? alguma idéia de quais poderiam ser as razões?
Dipti Mehta
@Andomar Desculpe abrir um tópico antigo. Um tem alguma vantagem sobre o outro - WebReference e ServiceReference? Eu acho que a primeira seria mais conveniente para mim, mas ServiceReference é o novo cool coisa que eu acho ...
Kev
17

Eu tive uma situação como essa, onde eu tive

  • Serviço WCF hospedado em algum lugar
  • Projeto Principal
  • Projeto do Consumidor do tipo 'biblioteca de classes' que possui referência de Serviço a um Serviço WCF
  • O projeto principal chama métodos do projeto do consumidor

Agora, o projeto Consumer tinha todas as definições de configuração relacionadas no <system.serviceModel>Tag do meu app.config, ainda estava gerando o mesmo erro que o anterior.

Tudo o que fiz foi adicionar a mesma tag <system.serviceModel>ao arquivo app.config do meu projeto principal e finalmente estávamos prontos.

O problema real, tanto quanto no meu caso, era ler o arquivo de configuração errado. Em vez do app.config do consumidor, ele se referia à configuração do projeto principal. Levei duas horas para descobrir isso.

Bravo
fonte
11
Mesmo. Pesquise <system.serviceModel>na sua biblioteca e copie-o no app.config do aplicativo principal. Apenas outro sintoma da biblioteca de classes app.configs não sendo lida em tempo de execução. Eu gasto muuuito tempo compensando essa supervisão (imo). Se eu quiser que a biblioteca leia sua configuração no app.config, deixe. Caso contrário, por que ter um app.config para bibliotecas de classes em primeiro lugar?
SteveCinq
15

"Este erro pode ocorrer se você estiver chamando o serviço em uma biblioteca de classes e chamando a biblioteca de classes de outro projeto."

"Nesse caso, você precisará incluir as definições de configuração do WS nos principais projetos app.config, se for um winapp ou web.config, se for um aplicativo da web. Este é o caminho a seguir, mesmo com PRISM e WPF / Silverlight."

Sim, mas se você não puder alterar o projeto principal (Orchard CMS, por exemplo), poderá manter a configuração do serviço WCF em seu projeto.

Você precisa criar um auxiliar de serviço com o método de geração de clientes:

public static class ServiceClientHelper
{
    public static T GetClient<T>(string moduleName) where T : IClientChannel
    {
        var channelType = typeof(T);
        var contractType = channelType.GetInterfaces().First(i => i.Namespace == channelType.Namespace);
        var contractAttribute = contractType.GetCustomAttributes(typeof(ServiceContractAttribute), false).First() as ServiceContractAttribute;

        if (contractAttribute == null)
            throw new Exception("contractAttribute not configured");

        //path to your lib app.config (mark as "Copy Always" in properties)
        var configPath = HostingEnvironment.MapPath(String.Format("~/Modules/{0}/bin/{0}.dll.config", moduleName)); 

        var configuration = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = configPath }, ConfigurationUserLevel.None);
        var serviceModelSectionGroup = ServiceModelSectionGroup.GetSectionGroup(configuration);

        if (serviceModelSectionGroup == null)
            throw new Exception("serviceModelSectionGroup not configured");

        var endpoint = serviceModelSectionGroup.Client.Endpoints.OfType<ChannelEndpointElement>().First(e => e.Contract == contractAttribute.ConfigurationName);
        var channelFactory = new ConfigurationChannelFactory<T>(endpoint.Name, configuration, null);
        var client = channelFactory.CreateChannel();
        return client;
    }
}

e use-o:

using (var client = ServiceClientHelper.GetClient<IDefaultNameServiceChannel>(yourLibName)) {
                ... get data from service ...
            }

Veja detalhes neste artigo .

melvas
fonte
15

Várias respostas aqui encontram a solução correta quando você está enfrentando o erro obscuro de referenciar o serviço de um arquivo de classe: copie as informações de configuração do serviço em seu app.config web.config do console ou aplicativo do Windows. Nenhuma dessas respostas parece mostrar o que copiar. Vamos tentar corrigir isso.

Aqui está o que eu copiei do arquivo de configuração da minha biblioteca de classes, no arquivo de configuração do meu aplicativo de console, para contornar esse erro louco de um serviço que eu escrevo chamado "TranslationServiceOutbound".

Você basicamente quer tudo dentro da seção system.serviceModel :

  <system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_ITranslationServiceOutbound" />
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://MyHostName/TranslationServiceOutbound/TranslationServiceOutbound.svc"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITranslationServiceOutbound"
    contract="TranslationService.ITranslationServiceOutbound" name="BasicHttpBinding_ITranslationServiceOutbound" />
</client>

markaaronky
fonte
14

Este me deixou louco.

Estou usando o Silverlight 3 Prism (CAB) com WCF

Quando chamo um serviço WCF em um módulo Prism, recebo o mesmo erro:

Não foi possível encontrar o elemento do terminal padrão que referencia o contrato 'IMyService' na seção de configuração do cliente do modelo de serviço. Isso pode ocorrer porque nenhum arquivo de configuração foi encontrado para o seu aplicativo ou porque nenhum elemento do terminal que corresponde a este contrato foi encontrado no elemento do cliente

Acontece que ele está procurando no arquivo .xap do Shell por um arquivo ServiceReferences.ClientConfig, não no arquivo ServiceReferences.ClientConfig do módulo. Adicionei meu nó de extremidade e a ligação ao arquivo ServiceReferences.ClientConfig existente no meu aplicativo Silverlight Shell (ele chama de serviços WCF próprios).

Tive que reconstruir o aplicativo Shell para gerar o novo arquivo .xap para a pasta ClientBin do meu projeto da Web.

Agora, essa linha de código finalmente funciona:

MyServiceClient myService = new MyServiceClient();
Jeff Moeller
fonte
11

Eu estava recebendo esse erro em um aplicativo ASP.NET em que o serviço WCF foi adicionado a uma biblioteca de classes que está sendo adicionada ao aplicativo ASP.NET como um arquivo .dll referenciado na pasta bin. Para resolver o erro, as definições de configuração no arquivo app.config na biblioteca de classes que faz referência ao serviço WCF precisavam ser copiadas nas configurações web.config do site / aplicativo ASP.NET.

zanderwel
fonte
Embora outras respostas possam ter descrito o mesmo problema. Esta resposta descreveu minha situação exata e finalmente entendi o problema. Obrigado por salvar o meu dia
Wouter Vanherck
10

Descobri (além de copiar para o App.config da interface do usuário do cliente enquanto estava usando uma interface da Biblioteca de classes) tive que prefixar o nome da ligação com o nome da Referência de serviço (a minha está ServiceReferenceabaixo).

por exemplo:

<endpoint address="http://localhost:4000/ServiceName" binding="basicHttpBinding"
      bindingConfiguration="BasicHttpBinding_ISchedulerService"
      contract="ServiceReference.ISchedulerService" 
      name="BasicHttpBinding_ISchedulerService" />

em vez do padrão gerado:

<endpoint address="http://localhost:4000/ServiceName" binding="basicHttpBinding"
      bindingConfiguration="BasicHttpBinding_ISchedulerService"
      contract="ISchedulerService" 
      name="BasicHttpBinding_ISchedulerService" />
Matt Mitchell
fonte
11
Eu tive de fazer a mesma coisa. Eu realmente não entendo o porquê.
Brig
8

Eu tive o mesmo problema, mas alterar o espaço para nome do contrato não funcionou para mim. Então, tentei uma referência da web em estilo .Net 2 em vez de uma referência de serviço .Net 3.5. Isso funcionou.

Para usar uma referência da Web no Visual Studio 2008, clique em 'Adicionar referência de serviço' e clique em 'Avançado' quando a caixa de diálogo aparecer. Nesse sentido, você encontrará uma opção que permitirá usar uma referência da Web em vez de uma referência de serviço.

Cyril Gupta
fonte
2
Foi isso que acabei fazendo também. Eu gostaria que o problema fizesse sentido para mim.
Jarrett Widman
Isso funcionou para mim também. Agora, tenho todo esse lixo extra em minha solução (Settings.Settings, uma nova pasta de referências da Web) sem um bom motivo. Terá que voltar e visitar novamente quando tiver mais tempo.
Mike K
Acordado. Eu tive o mesmo problema e o corrigi, alterando-o para uma referência da web.
Stephen Hosking
7

A unidade de teste de um aplicativo que não é da biblioteca que consome um serviço pode causar esse problema.

As informações inseridas por outras pessoas abordam a causa raiz disso. Se você estiver tentando escrever casos de teste automatizados e a unidade que estiver testando, na verdade, chamará a interface de serviço, será necessário adicionar a referência de serviço ao projeto de teste. Este é um sabor do aplicativo usando o tipo de erro de biblioteca. Eu não percebi isso imediatamente porque meu código que consome a interface não está em uma biblioteca . No entanto, quando o teste realmente for executado, ele será executado a partir do conjunto de teste, não do conjunto sob teste.

A adição de uma referência de serviço ao projeto de teste de unidade resolveu meu problema.

PatrickV
fonte
7

Eu tenho uma situação que no teste de unidade. Copiei o arquivo app.config para o projeto de teste da unidade. Portanto, o projeto de teste de unidade também contém informações de terminal.


fonte
2
Não copiei o app.config completo, mas a system.serviceModelseção. Isso é tudo!
kwrl
Mesmo, exceto eu copiei o system.serviceModelao app.config de um aplicativo de console
AlbatrossCafe
5

Eu enfrentei esse problema uma vez. Foi porque eu ainda estava desenvolvendo a interface que usa o serviço WCF. Eu configurei o aplicativo de teste e o desenvolvimento contínuo. Então, no desenvolvimento, mudei alguns namespaces dos serviços. Então, verifiquei "system.serviceModel -> client -> endpoint -> contract" no web.config para corresponder à classe WCF. Então o problema está resolvido.

vardars
fonte
4

O espaço para nome na sua configuração deve refletir o restante do caminho do espaço para nome após o espaço para nome padrão do seu cliente (conforme configurado nas propriedades do projeto). Com base na sua resposta postada, meu palpite é que seu cliente está configurado para estar no espaço de nome "Fusion.DataExchange.Workflows". Se você moveu o código do cliente para outro espaço para nome, seria necessário atualizar a configuração para corresponder ao caminho restante do espaço para nome.

Chris Porter
fonte
3

Estou usando o Serviço WCF na biblioteca de classes e chamando a biblioteca de classes do Windows Application project.but Estou esquecido Alterar <system.serviceModel>no arquivo de configuração do aplicativo windows Projete o mesmo do <system.serviceModel>arquivo app.Config da biblioteca de classes.
solução: mudança Configuração do projeto externo igual à configuração wcf da biblioteca de classes.

sAeid mOhammad Hashem
fonte
3

Oi Eu encontrei o mesmo problema, mas a melhor solução é deixar o .NET configurar a configuração do lado do cliente. O que eu descobri é isso quando adiciono uma referência de serviço com uma string de consulta http: /namespace/service.svc? Wsdl = wsdl0, NÃO cria pontos de extremidade de configuração no lado do cliente. Mas quando eu removo o? Wsdl-wsdl0 e só uso o URL http: /namespace/service.svc, ele cria a configuração do terminal no arquivo de configuração do cliente. para remoinho curto o "? WSDL = WSDL0".

Joey
fonte
3

Não coloque a linha de declaração do cliente de serviço como campo de classe; em vez disso, crie uma instância em cada método usado. Portanto, o problema será corrigido. Se você criar uma instância do cliente de serviço como campo de classe, ocorrerá um erro de tempo de design!

Mücahid Uslu
fonte
3

Caso você esteja usando o aplicativo WPF usando a estrutura PRISM, a configuração deve existir no seu projeto de inicialização (ou seja, no projeto em que o seu bootstrapper reside).

VRK
fonte
2

Este erro pode ocorrer se você estiver chamando o serviço em uma biblioteca de classes e a biblioteca de classes de outro projeto.

Manuel Alves
fonte
2

Parece haver várias maneiras de criar / corrigir esse problema. Para mim, o produto de CRM que estou usando foi escrito em código nativo e pode chamar minha dll .NET, mas encontro as informações de configuração que precisam estar no / acima do aplicativo principal. Para mim, o aplicativo de CRM não é .NET, então acabei tendo que colocá-lo no meu arquivo machine.config (não onde eu quero). Além disso, como minha empresa usa o Websense, tive dificuldade para adicionar a Referência de serviço devido a um problema 407 Proxy Authentication Required, que exigia uma modificação no machine.cong.

Solução de proxy:

Para que a Referência de Serviço do WCF funcionasse, tive que copiar as informações do app.config da minha DLL para a configuração principal do aplicativo (mas para mim era machine.config). E também tive que copiar as informações do terminal para o mesmo arquivo. Uma vez eu fiz isso, começando a trabalhar para mim.

TPaul
fonte
2

Está bem. Meu caso foi um pouco diferente, mas finalmente encontrei a correção para ele: Eu tenho um Console.EXE -> DLL -> Invocando o WS1 -> DLL -> Invocando o WS2

Eu tive as configurações do modelo de serviço do WS1 e WS2 no Console.EXE.config, conforme recomendado. - não resolveu o problema.

Mas ainda não funcionou, até que eu adicionei o WebReference do WS2 ao WS1 também e não apenas à DLL que realmente criou e invocou o proxy do WS2.

Itay Levin
fonte
2

Se você referenciar o serviço web na sua biblioteca de classes, precisará copiar app.config para o aplicativo Windows ou aplicativo de console

solução: mudança Configuração do projeto externo igual à configuração wcf da biblioteca de classes.

Trabalhou para mim

Roshan
fonte
2

Eu tive o mesmo problema
: estava usando o aplicativo de desktop e usando o serviço da Web Global Weather

Excluí a referência de serviço e adicionei a referência da web e o problema resolvido Obrigado

Kamran Akhter
fonte
2

A solução para mim foi remover o nome do terminal do atributo Nome do Terminal no cliente web.config, permitindo que o proxy usasse

ChannelFactory<TService> _channelFactory = new ChannelFactory<TService>("");

levou apenas o dia todo para malhar. Além disso, o nome do contrato estava errado quando essa correção estava em vigor, embora estivesse errado quando o erro inicial aparecer. Duplo, em seguida, tripla verificação de nome do contrato cordas pessoas !! attrib: Ian

roubar
fonte
2

Permita-me adicionar mais uma coisa para procurar. ( Tom Haigh's resposta de já faz alusão a isso, mas eu quero ser explícito)

Meu web.configarquivo tinha o seguinte definido:

<protocolMapping>
    <add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>

Eu já estava usando basicHttpsBinding para uma referência, mas adicionei uma nova referência que exigia basicHttpBinding (no s). Tudo o que eu precisava fazer era adicionar isso ao meu da protocolMappingseguinte maneira:

<protocolMapping>
    <add binding="basicHttpBinding" scheme="http" />
    <add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>

Como LR aponta corretamente, isso precisa ser definido nos lugares certos. Para mim, isso significava um no app.config do meu projeto de Teste de Unidade e outro no web.config do projeto de serviço principal.

David
fonte
2

Eu tive esse erro ao referenciar o contrato no elemento do arquivo de configuração sem o operador de escopo global.

ie

<endpoint contract="global::MyNamepsace.IMyContract" .../>

funciona, mas

<endpoint contract="MyNamepsace.IMyContract" .../>

fornece o erro "Não foi possível encontrar o elemento do terminal padrão que faz referência ao contrato".

O assembly que contém MyNamepsace.IMyContract está em um assembly diferente do aplicativo principal, portanto, isso pode explicar a necessidade de usar a resolução de escopo global.

veleiro
fonte
2

Quando você está adicionando uma referência de serviço

insira a descrição da imagem aqui

cuidado com o espaço para nome que você está digitando:

insira a descrição da imagem aqui

Você deve anexá-lo ao nome da sua interface:

<client>
  <endpoint address="http://192.168.100.87:7001/soap/IMySOAPWebService"
            binding="basicHttpBinding" 
            contract="MyNamespace.IMySOAPWebService" />
</client>
Waldemar Gałęzinowski
fonte
2

Eu recebi o mesmo erro e tentei muitas coisas, mas não funcionou, pois notei que meu "contrato" não era o mesmo em todos os projetos, mudei o contrato como seria o mesmo para todos os projetos dentro da solução e do que funcionou. Este é o projeto A

<client>
    <endpoint address="https://xxxxxxxx" binding="basicHttpBinding" bindingConfiguration="basic" contract="ServiceReference.IIntegrationService" name="basic" />
</client>

Projeto B:

<client>
    <endpoint address="xxxxxxxxxxxxx" binding="basicHttpBinding" bindingConfiguration="basic" contract="ServiceReference1.IIntegrationService" name="basic" />
</client>

Finalmente mudei para ambos como:

<client>
    <endpoint address="https://xxxxxxxxxxx" binding="basicHttpBinding" bindingConfiguration="basic" contract="MyServiceReferrence.IIntegrationService" name="basic" />
</client>
nzrytmn
fonte
1

Eu tive o mesmo problema e foi resolvido apenas quando o aplicativo host e a dll que usava esse ponto de extremidade tinham o mesmo nome de referência de serviço.

prata
fonte