2011-01-11 127 views
10

He pasado un par de horas buscando sobre este error, y he probado casi todo lo que está en Google.Metadatos WCF contiene una referencia que no se puede resolver

Quiero acceder a un servicio usando TCP, .NET4 y VS2010, en C#.

Tengo una muy pequeña del servicio:


namespace WcfService_using_callbacks_via_tcp 
{ 
    [ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)] 
    public interface IService1 
    { 
     [OperationContract] 
     string Test(int value); 
    } 

    public interface ICallback 
    { 
     [OperationContract(IsOneWay = true)] 
     void ServerToClient(string sms); 
    } 
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
    public class Service1 : IService1 
    { 
     public string Test(int value) 
     { 
      ICallback the_callback = OperationContext.Current.GetCallbackChannel<ICallback>(); 
      the_callback.ServerToClient("Callback from server, waiting 1s to return value."); 
      Thread.Sleep(1000); 
      return string.Format("You entered: {0}", value); 
     } 

    } 
} 

Con esta Web.config:


<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <services> 
     <service name="WcfService_using_callbacks_via_tcp.Service1" behaviorConfiguration="Behaviour_Service1"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="net.tcp://localhost:5050/Service1" /> 
      </baseAddresses> 
     </host> 
     <endpoint address="" binding="netTcpBinding" bindingConfiguration="DuplexNetTcpBinding_IService1" contract="WcfService_using_callbacks_via_tcp.IService1"/> 
     <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="mexTcp" contract="IMetadataExchange"/> 
     </service> 
    </services> 

    <bindings> 
     <!-- 
     TCP Binding 
     --> 
     <netTcpBinding> 
     <binding name="DuplexNetTcpBinding_IService1" sendTimeout="00:00:01" 
       portSharingEnabled="true"> 

     </binding> 

     <binding name="mexTcp" portSharingEnabled="true"> 
      <security mode="None" /> 
     </binding> 
     </netTcpBinding> 


    </bindings> 

    <behaviors> 
     <serviceBehaviors> 
     <!-- 
      Behaviour to avoid a rush of clients and to expose metadata over tcp 
     --> 
     <behavior name="Behaviour_Service1"> 
      <serviceThrottling maxConcurrentSessions="10000"/> 
      <serviceMetadata httpGetEnabled="true"/> 
     </behavior> 

     <behavior> 
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> 
      <serviceMetadata httpGetEnabled="true"/> 
      <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 

</configuration> 

Y Thi código s de ser el anfitrión:


static void Main(string[] args) 
{ 
    Uri base_address = new Uri("net.tcp://localhost:5050/Service1"); 
    ServiceHost host = null; 
    try 
    { 
     // Create the server 
     host = new ServiceHost(typeof(Service1), base_address); 
     // Start the server 
     host.Open(); 
     // Notify it 
     Console.WriteLine("The service is ready at {0}", base_address); 
     // Allow close the server 
     Console.WriteLine("Press <Enter> to stop the service."); 
     Console.ReadLine(); 
     // Close it 
     host.Close(); 
    } 
    catch (Exception ex) 
    { 
     // Opus an error occurred 
     Console.ForegroundColor = ConsoleColor.Red; 
     Console.WriteLine(string.Format("Host error:\r\n{0}:\r\n{1}", ex.GetType(), ex.Message)); 
     Console.ReadLine(); 
    }finally 
    { 
     // Correct memory clean 
     if(host != null) 
      ((IDisposable)host).Dispose(); 
    } 
} 

Ahora quiero crear el cliente, pero no es posible. He usado Agregar referencia de servicio y Svcutil directamente, pero estoy recibiendo este error:


C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>svcutil.exe net.tcp://loc alhost:5050/Service1 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 'net.tcp://localhost:5050/Service1' using W S-Metadata Exchange. This URL does not support DISCO. Microsoft (R) Service Model Metadata Tool [Microsoft (R) Windows (R) Communication Foundation, Version 4.0.30319.1] Copyright (c) Microsoft Corporation. All rights reserved.

Error: Cannot obtain Metadata from net.tcp://localhost:5050/Service1

If this is a Windows (R) Communication Foundation service to which you have acce ss, please check that you have enabled metadata publishing at the specified addr ess. For help enabling metadata publishing, please refer to the MSDN documentat ion at http://go.microsoft.com/fwlink/?LinkId=65455 .

WS-Metadata Exchange Error URI: net.tcp://localhost:5050/Service1

Metadata contains a reference that cannot be resolved: 'net.tcp://localhost: 5050/Service1'.

The socket connection was aborted. This could be caused by an error processi ng your message or a receive timeout being exceeded by the remote host, or an un derlying network resource issue. Local socket timeout was '00:04:59.9863281'.

Se ha forzado la interrupción de una conexión existente por el host remoto

If you would like more help, type "svcutil /?"


lo tanto, puedo alojar el servicio sin problemas, pero no puedo crear los proxies.

He intentado con casi cualquier configuración que he encontrado, pero creo que la web.config actual es correcta. Existen los comportamientos, la seguridad y los enlaces que usan mex, utilizados por los puntos finales.

He intentado crear un app.config y configurarlo en la misma carpeta con svcutil.exe.

+0

@JohnSaunders, no puedo comprender por qué alguien con su reputación copiaría el código de respuesta en el código de la pregunta, lo que invalidaría por completo toda esta pregunta. Solo perdí el tiempo tratando de resolver la diferencia entre el código de pregunta y el código de respuesta antes de darme cuenta de que alguien había hecho lo que tú hiciste ... ¿Cuál es el beneficio al hacer eso? Nadie podía saber cuál era la verdadera pregunta. – Sheridan

+0

@Sheridan: aquí hay una gran sugerencia de vida: cada vez que te encuentras diciendo cosas como "No puedo entender cómo" o "No puedo ver cómo", considera que podría ser una cuestión de tu comprensión o tu visión . Usted "no puede entender cómo" porque no lo hice. Acabo de sangrar el código. Eche un vistazo más de cerca al historial de edición. Lo acabo de hacer. –

+1

I * did * eché un vistazo de cerca * antes * de mi comentario y, aunque acepto su comentario, me gustaría decir que aún * aparece * como si hubiera agregado ese código ... ahhh ... eso está solo en el * Vista de lado a lado *. En las otras vistas, puedo ver la verdadera imagen. Disculpas ... Debería haber mirado más de cerca antes de comentar. – Sheridan

Respuesta

8

Te faltan configuración del servicio

<system.serviceModel> 
    <services> 
    <service name="WcfService_using_callbacks_via_tcp.Service1" 
     behaviorConfiguration="Behavior_Service1"> 
     <host> 
     <baseAddresses> 
      <add baseAddress="net.tcp://localhost:5050/Service1" /> 
     </baseAddresses> 
     </host> 
     <endpoint address="" contract="WcfService_using_callbacks_via_tcp.IService1" 
     binding="netTcpBinding" bindingConfiguration="DuplexNetTcpBinding_IService1" /> 
     <endpoint address="mex" contract="IMetadataExchange" binding="mexTcpBindng" /> 
    </service> 
    </services> 
    ... 
</system.serviceModel> 

Con esta configuración que no es necesario definir la dirección base en el código.

+0

Gracias por la respuesta. No estaba configurando la aplicación.config correctamente en el proyecto de la consola de mi servidor. He declarado los enlaces y comportamientos en el código antes del host.Open(); Y funcionó. – JoanComasFdz

+0

No olvide marcar como respuesta si esto resuelve su problema, por favor – Shenaniganz

1

Tuve el mismo problema (cuando el cliente no "veía" el servicio en el menú "Agregar referencia de servicio") al usar solo el enlace tcp. Después de intentar agregar Comportamiento, mi servicio finalizó con excepción porque no encontró la dirección correcta. No sé si es la mejor idea, pero puede agregar la dirección de segunda base como http .... aquí está mi configuración y código, funciona.

<?xml version="1.0" encoding="utf-8" ?><configuration> <system.serviceModel> <services> 
    <service name="TestBindings.StockQuoteService"> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://10.62.60.62:34000/StockQuoteService" /> 
     <add baseAddress ="http://10.62.60.62:12000/StockQuoteService"/> 
     </baseAddresses> 
    </host> 
    <endpoint address="" 
    contract="TestBindings.IStockQuoteService" 
    binding="netTcpBinding" /> 
    </service> 
</services> 

Y el código

class Program 
{ 
    static void Main(string[] args) 
    { 
     ServiceHost sh = new ServiceHost(typeof(StockQuoteService)); 
     ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); 
     behavior.HttpGetEnabled = true; 
     sh.Description.Behaviors.Add(behavior); 
     sh.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), 
      "mex"); 
     sh.Open(); 

la dirección HTTP está ahora USEND por el cliente para agregar referencia de servicio, y automáticamente genera config en el lado del cliente utiliza el protocolo net.tcp para llamar al función.

+0

Parece una buena solución, y parece lógico, pero una vez que se ha generado su cliente, ¿necesita la dirección http? – JoanComasFdz

+1

La dirección http no es necesaria si tiene un cliente. Pero si necesita generar algunos clientes en el futuro, es mejor tenerlo en la configuración. – Anna

2

que estaba recibiendo el mismo mensaje de error y como se vio después, el problema era debido a texto dentro de un comentarios bloquean

<!-- comments included characters like à, ç and ã --> 

Después de la eliminación de tales personajes del bloque comentado, todo funciona bien

3

Recibí el mismo error al intentar actualizar una referencia de servicio existente. Resulta que tenía contratos de datos con el mismo nombre dentro del mismo espacio de nombres. La investigación adicional produjo el error real:

DataContract for type [redacted] cannot be added to DataContractSet since type '[redacted]' with the same data contract name 'DocumentInfo' in namespace '[redacted]' is already present and the contracts are not equivalent.

Cambié el DataContract para proporcionar un nombre para una de las clases.

[DataContract(Namespace = "urn:*[redacted]*:DataContracts", Name = "SC_DocumentInfo")] 

Lo escribo aquí en caso de que pueda ayudar a alguien con el mismo problema.

+0

Estoy bastante seguro de que este es mi problema, porque cambié varios contratos de datos. Me pregunto qué hizo para obtener el mensaje mencionado. El mensaje ayudaría a averiguar qué DataContract ya existe –

+0

@HaraldCoppoolse Intenté ver el servicio en un navegador y apareció un error más detallado. Estoy usando VS 2015, navegué hasta el servicio, hice clic derecho sobre él y seleccioné Ver en el navegador. ¡Espero que eso te ayude! – mslissap

1

Quizás sea útil para alguien.

Mi problema estaba en un argumento contrato, y descubrí que con la ayuda de Visor de sucesos:

The operation [Name of method] either has a parameter or a return type that is attributed with MessageContractAttribute. In order to represent the request message using a Message Contract, the operation must have a single parameter attributed with MessageContractAttribute. In order to represent the response message using a Message Contract, the operation's return value must be a type that is attributed with MessageContractAttribute and the operation may not have any out or ref parameters.

lo tanto, si añadida automáticamente a más de un argumento, ya argumento que tiene [MessageContract], entonces Veremos el error en cuestión. Completamente no obvio.

Cuestiones relacionadas