【问题标题】:Problem addressing a service in WCF在 WCF 中解决服务的问题
【发布时间】:2011-05-12 21:28:30
【问题描述】:

我正在使用 wcf 编写服务。 我创建了一个包含两个项目的解决方案:

  • 库: 一个项目,用于存储有关服务的文件(包含该服务的接口和相应的实现)。这个项目是一个图书馆项目。
  • 托管应用程序 托管这些服务的项目(自托管)。出于这个原因,这个项目是一个可执行项目,它有一个配置文件,我在其中放置了配置服务所需的信息。

我还编写了一个客户端来调用该服务。这将被称为客户端应用程序

我有一个服务。以下是接口和实现(库项目):

namespace EchoWcfLibrary {
    /// <summary>
    /// The interface specifies for those classes implementing it (services), the operation that the service will expose.
    /// </summary>
    [ServiceContract]
    public interface IService1 {
        // This does not use serialization (implicit serialization in considered: base types used).
        [OperationContract]
        string GetData(int value);
        // This uses data contracts and serialization.
        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);
    }

    [DataContract]
    public class CompositeType {
        // Members not serialized
        bool boolValue = true;
        string stringValue = "Hello ";
        // Serialized
        [DataMember]
        public bool BoolValue {
            get { return boolValue; }
            set { boolValue = value; }
        }
        // Serialized
        [DataMember]
        public string StringValue {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }
}

以下是服务宿主应用程序(可执行项目)的启动:

namespace WcfServiceApplication {
    public static class Program {
        static void Main(string[] args) {
            // Setting endpoints and setting the service to start properly.
            // Base address specified: http://localhost:8081/Service1
            Console.WriteLine("Beginning...");
            using (ServiceHost host = new ServiceHost(typeof(Service1), new Uri("http://localhost:8081/Service1"))) {
                Console.WriteLine("Opening host...");
                host.Open();
                Console.WriteLine("Waiting...");
                System.Threading.Thread.Sleep(1000000);
                Console.WriteLine("Closing...");
                host.Close();
                Console.WriteLine("Quitting...");
            }
        }
    }
}

以下是可执行项目(宿主应用程序)中的App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
    <system.serviceModel>
        <services>
            <service name="WcfServiceLibrary.Service1">
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8081/Service1" />
                    </baseAddresses>
                </host>
                <!-- Service Endpoints -->
                <!-- Unless fully qualified, address is relative to base address supplied above -->
                <endpoint address="/GoInto/Svc" 
                                    binding="basicHttpBinding" 
                                    contract="WcfServiceLibrary.IService1">
                    <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
                    <identity>
                        <dns value="localhost"/>
                    </identity>
                </endpoint>
                <endpoint address="/GoInto/Sav"
                                    binding="basicHttpBinding"
                                    contract="WcfServiceLibrary.IService1">
                    <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
                    <identity>
                        <dns value="localhost"/>
                    </identity>
                </endpoint>
                <!-- Metadata Endpoints -->
                <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
                <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
                <endpoint address="GoInto/Mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            </service>
        </services>

        <behaviors>
            <serviceBehaviors>
                <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>
    </system.serviceModel>

</configuration>

以下是客户端可执行项目中的程序启动(已链接库项目),基本上是客户端:

namespace WcfServiceClient {
    class Program {
        static void Main(string[] args) {
            ServiceEndpoint httpEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IService1)), new BasicHttpBinding(), new EndpointAddress("http://localhost:8081/Service1"));
            ChannelFactory<IService1> channelFactory = new ChannelFactory<IService1>(httpEndpoint);
            IService1 svc = channelFactory.CreateChannel();
            Console.WriteLine(svc.GetData(121));
            System.Threading.Thread.Sleep(10000);
        }
    }
}

嗯......我的问题如下:这个应用程序工作! 为什么会有问题??? 问题是我在托管服务时在App.config 文件中指定了三个端点:两个basicHttp 和一个元数据端点。好吧,我想解决 &lt;endpoint address="/GoInto/Svc"... 端点,我假设这是完整的地址(注意我已经指定了一个基地址):http://localhost:8081/Service1/GoInto/Svc

好吧,不幸的是,在客户端中,我处理了这个端点:http://localhost:8081/Service1 这只是基地址......为什么它工作????我想在客户端指定这个地址:

namespace WcfServiceClient {
    class Program {
        static void Main(string[] args) {
            ServiceEndpoint httpEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IService1)), new BasicHttpBinding(), new EndpointAddress("http://localhost:8081/Service1/GoInto/Svc"));
            ChannelFactory<IService1> channelFactory = new ChannelFactory<IService1>(httpEndpoint);
            IService1 svc = channelFactory.CreateChannel();
            Console.WriteLine(svc.GetData(121));
            System.Threading.Thread.Sleep(10000);
        }
    }
}

但如果我这样做,则会引发不匹配错误:

带有To的消息 'http://localhost:8081/Service1/GoInto/Svc' 无法在接收方处理, 由于 AddressFilter 不匹配 端点调度程序。检查 发送者和接收者的 EndpointAddresses 同意。

为什么它不起作用?

【问题讨论】:

    标签: c# .net wcf service


    【解决方案1】:

    基地址必须在一处指定,要么在 ServiceHost 构造函数中,要么在元素中。如果你在这两个地方都有,WCF 会抛出一个异常,说你有两个基地址用于相同的方案 (HTTP)。

    可能发生的情况是您在托管项目的 app.config 上的服务名称不匹配,因此配置没有被拾取(您得到的是一个默认端点,其地址是相同的一个作为基地址)。尝试在您的托管代码中添加 foreach 循环,您应该会看到您的服务正在侦听的端点的地址。

                    Console.WriteLine("Opening host...");
                host.Open();
    
                foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
                {
                    Console.WriteLine("Endpoint:");
                    Console.WriteLine("   Address: {0}", endpoint.Address.Uri);
                    Console.WriteLine("   Binding: {0}", endpoint.Binding);
                    Console.WriteLine("   Contract: {0}", endpoint.Contract.Name);
                }
    
                Console.WriteLine("Waiting...");
    

    【讨论】:

      猜你喜欢
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多