开发者

WCF Metadata contains a reference that cannot be resolved

I've spent a couple of hours searching about this error, and I have tested almost everything it's on Google.

I want to access a service using TCP, .NET4 and VS2010, in C#.

I Have a very tiny service:


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

    }
}

With this 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
   开发者_StackOverflow社区   -->
      <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>

And this code to host it:


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

Now I want to create the client, but I it is not posible. I've used Add Service Reference and svcutil directly, but I am receiving this 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 /?"


So, I can host the service without problems but I can not create the proxies.

I've tried almost any config I've found, but I think the current web.config is correct. There are the behaviours, the security, and the bindings using mex, used by the endpoints.

I've tried to create an app.config and set it to the same folder with svcutil.exe.


You are missing service configuration

<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>

With this config you should not need to define base address in code.


I received the same error while attempting to update an existing service reference. It turns out I had data contracts with the same name within the same namespace. Further investigation yielded the real error:

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.

I changed the DataContract to provide a name for one of the classes.

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

I'm posting this here in case it might help someone with the same issue.


I was getting the same error message and as it turned out, the issue was due to text within a comments block

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

After removing such characters from the commented block, everything works fine


Maybe it will be helpful for someone.

My issue was in a contract argument, and I discovered it with help of Event Viewer:

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.

So, if you appended more than one arguments, already having [MessageContract] argument, then you'll see error in question. Completely not obvious.


I had the same problem (when client didn't "see" the service in "Add service reference" menu) while using only tcp binding. After trying to add Behavior I had my service to end with exception because it didn't find proper address. I don't know if it is the best idea, but you can add second base address as http.... here is my config and code, it works.

    <?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>

And the code

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

The http address is now usend by client to add service reference, and automatically generated config on client side uses net.tcp protocol to call the function.


There is yet another reason to run into this one. Similar to the DataContract related answer here, WCF services also don't support method overloading in operation contracts. It'll raise this confusing catch-all exception as well.

The fix is simple enough:

        [OperationContract]
        T[] Query(int id);

        [OperationContract(Name = "QueryWithArg")]
        T[] Query(int id, string arg);


For the above issue check the reference.svc file which is generated at the time you add the reference. The url mentioned in that will be used for updating the service so you can check whether that is running or not.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜