none
请教两个同名契约(命名空间不同)能否在同一客户端配置中并存 RRS feed

  • 问题

  • 我有两个Service,接口名相同,命名空间不同,发布地址也不同,服务端配置信息分别是:

           <service behaviorConfiguration="DefaultBehavior" name="Company.Security.Service.CodeHeaderService">
              <endpoint address="" binding="wsHttpBinding" bindingConfiguration="DefaultBinding"
                 contract="Company.Security.Service.ICodeHeaderService" />
              <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
           </service>

          <service behaviorConfiguration="DefaultBehavior" name="Company.Project.Service.Configuration.CodeHeaderService">
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="DefaultBinding"
                      contract="Company.Project.Service.Configuration.ICodeHeaderService" />      
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>  

    现在我想在同一个客户端中根据不同情况调用两个不同的Service,客户端自动生成的配置信息是:

          <endpoint address="http://localhost:1491/CodeHeaderService.svc"
              binding="wsHttpBinding"
              bindingConfiguration="DefaultBinding"
              contract="ICodeHeaderService"
              name="WSHttpBinding_ICodeHeaderService">
          </endpoint>

          <endpoint address="http://localhost:10728/CodeHeaderService.svc"
              binding="wsHttpBinding"
              bindingConfiguration="DefaultBinding"
              contract="ICodeHeaderService"
              name="WSHttpBinding_ICodeHeaderService">
          </endpoint>

    此时运行客户端,提示“在同一配置范围中已经存在名称为“endpoint”且具有相同密钥的子元素。在同一配置范围(例如同一个 application.config 文件)中,集合元素必须是唯一的。”

    然后我把客户端配置的contract中加入命名空间:

          <endpoint address="http://localhost:1491/CodeHeaderService.svc"
              binding="wsHttpBinding"
              bindingConfiguration="DefaultBinding"
              contract="Company.Security.Service.ICodeHeaderService"
              name="WSHttpBinding_ICodeHeaderService">
          </endpoint>

          <endpoint address="http://localhost:10728/CodeHeaderService.svc"
              binding="wsHttpBinding"
              bindingConfiguration="DefaultBinding"
              contract="Company.Project.Service.Configuration.ICodeHeaderService"
              name="WSHttpBinding_ICodeHeaderService">
          </endpoint>

    依然报错,但提示变成了“在 ServiceModel 客户端配置部分中,找不到引用协定“ICodeHeaderService”的默认终结点元素。这可能是因为未找到应用程序的配置文件,或者是因为客户端元素中找不到与此协定匹配的终结点元素。”

    请问这种情况应该如何处理?难道只能把其中的某个Interface改名吗?有没有更好的方式?谢谢。

    2009年5月25日 6:32

答案

  •           contract="Company.Security.Service.ICodeHeaderService"

              contract="Company.Project.Service.Configuration.ICodeHeaderService"
    我给个建议,你试验一下~:
    你的终结点地址信息没有问题,我直觉是服务契约的问题。
    你的客户端代码是添加元数据自动反序列化生成的是吧。
    那没找到reference.cs文件,查看客户端对应的两个契约ICodeHeaderService。他们应该有不同的命名控件在客户端。

       现在你配置文件里终结点的contract直接配置的是服务端程序集命名空间的信息。应该和客户端的对应。

      你试一下~ 个人意见,仅供参考~


    you have a dream,you gonna protect it! http://www.cnblogs.com/frank_xl
    • 已标记为答案 cxy 2009年5月25日 9:36
    2009年5月25日 9:11
    版主
  • 刚注意到客户端代理类中有个Attribute是指定配置名称的:

        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "ICodeHeaderService")]
        public interface ICodeHeaderService
        {
            //...
        }

    默认生成的两个客户端代理类,这个配置名称都是一样的,所以会报错,现在把这个配置名和配置信息分别改成如下方式后,问题解决,感谢大家的关注,谢谢Frank Xu Lei的回复

    namespace Company.Project.Service.Proxy
    {
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "Company.Project.Service.Proxy.ICodeHeaderService")]
        public interface ICodeHeaderService
        {
            //...
        }
    }

    <endpoint address="http://localhost:10728/CodeHeaderService.svc"
        binding="wsHttpBinding"
        bindingConfiguration="DefaultBinding"
        contract="Company.Project.Service.Proxy.ICodeHeaderService"
        name="WSHttpBinding_ICodeHeaderService">
    </endpoint>

    namespace Company.Security.Proxy
    {
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "Company.Security.Proxy.ICodeHeaderService")]
        public interface ICodeHeaderService
        {
            //...
        }
    }

    <endpoint address="http://localhost:1491/CodeHeaderService.svc"
        binding="wsHttpBinding"
        bindingConfiguration="DefaultBinding"
        contract="Company.Security.Proxy.ICodeHeaderService"
        name="WSHttpBinding_ICodeHeaderService">
    </endpoint>
    • 已标记为答案 cxy 2009年5月25日 9:36
    • 已编辑 cxy 2009年5月25日 9:56
    2009年5月25日 9:35

全部回复

  •           contract="Company.Security.Service.ICodeHeaderService"

              contract="Company.Project.Service.Configuration.ICodeHeaderService"
    我给个建议,你试验一下~:
    你的终结点地址信息没有问题,我直觉是服务契约的问题。
    你的客户端代码是添加元数据自动反序列化生成的是吧。
    那没找到reference.cs文件,查看客户端对应的两个契约ICodeHeaderService。他们应该有不同的命名控件在客户端。

       现在你配置文件里终结点的contract直接配置的是服务端程序集命名空间的信息。应该和客户端的对应。

      你试一下~ 个人意见,仅供参考~


    you have a dream,you gonna protect it! http://www.cnblogs.com/frank_xl
    • 已标记为答案 cxy 2009年5月25日 9:36
    2009年5月25日 9:11
    版主
  • 谢谢你的回复,我的客户端代码是通过svcutil.exe生成的,没有直接用添加服务引用的方式,因为个人觉得那样生成的冗余代码比较多:

    svcutil.exe http://localhost:10728/CodeHeaderService.svc?wsdl

    自动生成的客户端代码如下(生成的代码中没有指定命名空间,所以命名空间是我自己手动加的):

    namespace Company.Project.Service.Proxy
    {
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "ICodeHeaderService")]
        public interface ICodeHeaderService
        {
            //...
        }

        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        public interface ICodeHeaderServiceChannel : ICodeHeaderService, System.ServiceModel.IClientChannel
        {
            //...
        }

        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        public partial class CodeHeaderServiceClient : System.ServiceModel.ClientBase<ICodeHeaderService>, ICodeHeaderService
        {
            //...
        }
    }

    我之前在配置文件中添加的contract="Company.Project.Service.Configuration.ICodeHeaderService"的确取的是服务端的命名空间,应该错了,但是现在我改用contract="Company.Project.Service.Proxy.ICodeHeaderService"还是提示“找不到引用协定“ICodeHeaderService”的默认终结点元素。”

    2009年5月25日 9:25
  • 刚注意到客户端代理类中有个Attribute是指定配置名称的:

        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "ICodeHeaderService")]
        public interface ICodeHeaderService
        {
            //...
        }

    默认生成的两个客户端代理类,这个配置名称都是一样的,所以会报错,现在把这个配置名和配置信息分别改成如下方式后,问题解决,感谢大家的关注,谢谢Frank Xu Lei的回复

    namespace Company.Project.Service.Proxy
    {
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "Company.Project.Service.Proxy.ICodeHeaderService")]
        public interface ICodeHeaderService
        {
            //...
        }
    }

    <endpoint address="http://localhost:10728/CodeHeaderService.svc"
        binding="wsHttpBinding"
        bindingConfiguration="DefaultBinding"
        contract="Company.Project.Service.Proxy.ICodeHeaderService"
        name="WSHttpBinding_ICodeHeaderService">
    </endpoint>

    namespace Company.Security.Proxy
    {
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
        [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "Company.Security.Proxy.ICodeHeaderService")]
        public interface ICodeHeaderService
        {
            //...
        }
    }

    <endpoint address="http://localhost:1491/CodeHeaderService.svc"
        binding="wsHttpBinding"
        bindingConfiguration="DefaultBinding"
        contract="Company.Security.Proxy.ICodeHeaderService"
        name="WSHttpBinding_ICodeHeaderService">
    </endpoint>
    • 已标记为答案 cxy 2009年5月25日 9:36
    • 已编辑 cxy 2009年5月25日 9:56
    2009年5月25日 9:35
  •   不要客气,互相交流学习~
       你使用svcutil生成客户端代码。有问题,其实直接添加服务引用反序列化的本地代码也会有问题。但是编译以后检查修改还是很快的。~毕竟工具不是那么的智能。
     
    you have a dream,you gonna protect it! http://www.cnblogs.com/frank_xl
    2009年5月25日 15:57
    版主