Erro de inicialização do serviço WCF "Esta coleção já contém um endereço com o esquema http"

182

Eu construí um aplicativo da Web que contém um contrato de serviço WCF e um controle Silverlight que faz chamadas para esse serviço WCF. Nos meus servidores de desenvolvimento e teste, ele funciona muito bem.

Quando implanto em nosso servidor System.ServiceModel.ServiceActivationExceptionativo e executo o aplicativo, recebo uma exceção do tipo que afirma que o serviço não pode ser ativado devido a uma exceção durante a compilação. A exceção é:

Esta coleção já contém um endereço com o esquema http. Pode haver no máximo um endereço por esquema nesta coleção.

Eu li que essa exceção pode ser lançada se o site tiver mais de um cabeçalho de host, o que é verdade em nosso servidor ativo. Aparentemente, os serviços WCF hospedados no IIS podem ter apenas um endereço base. Como posso contornar esse problema?

Jeremy
fonte

Respostas:

167

No .Net 4, você pode usar a multipleSiteBindingsEnabledopção:

<system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true">
    </serviceHostingEnvironment>
</system.serviceModel>

Então, você não precisará especificar cada endereço.

http://msdn.microsoft.com/en-us/library/system.servicemodel.servicehostingenvironment.multiplesitebindingsenabled.aspx

ericvg
fonte
Sim, mas isso funciona apenas com o .NET 4.0 e superior. Não é possível usar isso com sites .NET 2.0 / 3.0 / 3.5.
Bytemaster
2
Nota - há um erro de digitação aqui - não há fechamento>, portanto, se você copiar e colar, terá problemas
sydneyos
2
Não funcionará para esta pergunta: "Esta funcionalidade está disponível apenas usando o protocolo HTTP".
George Tsiokos
146

Resumo,

Solução de código: Aqui

Soluções de configuração: Aqui

Com a ajuda de Mike Chaliy , encontrei algumas soluções sobre como fazer isso através do código. Como esse problema afetará praticamente todos os projetos que implementamos em um ambiente ativo, eu ofereci uma solução puramente de configuração. Acabei encontrando um que detalha como fazer isso no .net 3.0 e no .net 3.5.

Retirado do site, abaixo está um exemplo de como alterar a configuração da web de seus aplicativos:

<system.serviceModel>
    <serviceHostingEnvironment>
        <baseAddressPrefixFilters>
            <add prefix="net.tcp://payroll.myorg.com:8000"/>
            <add prefix="http://shipping.myorg.com:9000"/>
        </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
</system.serviceModel>

No exemplo acima, net.tcp: //payroll.myorg.com: 8000 e http://shipping.myorg.com:9000 são os únicos endereços de base, para seus respectivos esquemas, aos quais será permitido passar. O baseAddressPrefixFilter não suporta nenhum curinga.

Os baseAddresses fornecidos pelo IIS podem ter endereços vinculados a outros esquemas não presentes na lista baseAddressPrefixFilter. Esses endereços não serão filtrados.

Solução de DNS (não testada): acho que se você criou uma nova entrada de DNS específica para seu aplicativo da Web, adicionou um novo site e forneceu um único cabeçalho de host correspondente à entrada de DNS, você mitigaria esse problema completamente e não faria isso. precisa escrever um código personalizado ou adicionar prefixos ao seu arquivo web.config.

Jeremy
fonte
2
A adição do filtro de prefixo do endereço base ao web.config funcionou perfeitamente. Obrigado Jeremy!
7279 Mike737
2
Eu não posso pensar em qualquer razão para que alguém iria querer essa restrição, muito menos a configuração padrão ...
PBZ
42
Estou começando a pensar mal sobre o WCF em combinação com o ASP.net e os serviços da web acessados ​​por JavaScript. Eu tive muito menos problemas com os serviços ASMX velhos lisos ...
Juri
Ok, e se você tiver um site com uma mistura de aplicativos .net 4 e .net 2 em execução nele. A base do aplicativo é .net4 e existem vários aplicativos que requerem .net2. Você usa <serviceHostingEnvironment multipleSiteBindingsEnabled = "true"> em todos os arquivos .net4 e o prefixo nos aplicativos .net 2?
Travis
59

Você viu isso - http://kb.discountasp.net/KB/a799/error-accessing-wcf-service-this-collection-already.aspx

Você pode resolver esse erro alterando o arquivo web.config.

Com o ASP.NET 4.0, adicione as seguintes linhas ao seu web.config:

<system.serviceModel> 
     <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
</system.serviceModel> 

Com o ASP.NET 2.0 / 3.0 / 3.5, adicione as seguintes linhas ao seu web.config:

<system.serviceModel> 
     <serviceHostingEnvironment> 
          <baseAddressPrefixFilters> 
               <add prefix="http://www.YourHostedDomainName.com"/> 
          </baseAddressPrefixFilters> 
     </serviceHostingEnvironment> 
</system.serviceModel> 
Mike Chaliy
fonte
Obrigado. Vou continuar pesquisando para ver se há uma solução que não seja de código. Algo que pode ser feito na configuração, porque isso afetará qualquer projeto que realizamos. Espero não ter que escrever um código personalizado.
1813 Jeremy
16

No meu caso, a causa raiz desse problema foi várias ligações http definidas no site pai, ou seja, InetMgr-> Sites-> Mysite-> properties-> EditBindings. Excluí uma ligação http que não era necessária e o problema foi resolvido.

Amar
fonte
1
Sim, Amar, isso foi muito útil - no meu caso, foi OUTRO site com várias ligações que o quebrou. Disponível externamente na mesma máquina (mas com um nome de host diferente). Da mesma forma, poderia ser corrigido adicionando a configuração multipleSiteBindingsEnabled, mas o web.config seria diferente de todos os outros ambientes.
The Coder
2
É uma pena que isso esteja no fundo. No nosso caso, isso foi corrigido para nós.
Brendonparker
Isso me ajudou a replicar o erro no ambiente de desenvolvimento. Não consigo editar ligações de sites em ambientes de certificação nem de produção. Alterei meu arquivo de hosts para simular um domínio e adicionei ligações ao IIS e bam locais!
MFedatto 5/05
8

E, no meu caso, era simples: usei o assistente 'Adicionar serviço WCF' no Visual Studio, que criou automaticamente as seções correspondentes no app.config. Então continuei lendo Como: Hospedar um serviço WCF em um aplicativo gerenciado . O problema era: eu não precisava especificar o URL para executar o serviço da web.

Substituir:

using (ServiceHost host = new ServiceHost(typeof(HelloWorldService), baseAddress))

Com:

using (ServiceHost host = new ServiceHost(typeof(HelloWorldService))

E o erro se foi.

Ideia genérica: se você fornecer o endereço base como um parâmetro e especificá-lo em config, receberá este erro. Muito provavelmente, essa não é a única maneira de obter o erro, tu.

bohdan_trotsenko
fonte
Resolveu o meu problema.
QShengyao 01/09
2

Eu tive esse problema, e a causa foi bastante tola. Eu estava testando a demonstração da Microsoft sobre a execução de um ServiceHost com um executável de linha de comando. Eu segui as instruções, incluindo onde diz para adicionar o serviço (e a interface) apropriados. Mas eu recebi o erro acima.

Acontece que quando adicionei a classe de serviço, o VS adicionou automaticamente a configuração ao app.config. E a demo estava tentando adicionar essas informações também. Como ele já estava na configuração, removi a parte demo e funcionou.

Eric
fonte
0

Eu vim pelo mesmo erro em um antigo Exchange Server 2010. Um serviço (serviço de replicação de caixa de correio do Exchange) estava emitindo o erro acima e o processo de migração não pôde ser continuado. Pesquisando pela internet, eu vim por este link que dizia o seguinte:

O GRE do Exchange falha ao abrir quando instalado pela primeira vez ou se forem feitas alterações no servidor IIS. Ele falha com o erro do snap-in e quando você tenta abrir a página do snap-in, o seguinte conteúdo é exibido:

This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection. If your service is being hosted in IIS you can fix the problem by setting 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' to true or specifying 'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'."

Causa : Este erro ocorre porque o número da porta http 443 já está sendo usado por outro aplicativo e o servidor IIS não está configurado para lidar com várias ligações à mesma porta.

Solução : configure o servidor IIS para lidar com várias ligações de porta. Entre em contato com o fornecedor (Microsoft) para configurá-lo.

Como esses serviços eram oferecidos a partir de um servidor Web IIS, a verificação das ligações no site raiz corrigia o problema. Alguém havia estragado as Ligações ao Site, definindo regras que se sobrepunham e estragando os serviços.

A correção das ligações corretas resolveu o problema, no meu caso, e não precisei configurar o Web.Config.

jimas13
fonte