WCF具有重复方法名称的多个合同

Hax*_*lit 5 c# wcf

我有一个像这样的多个合同的服务.

[ServiceContract]
public partial interface IBusinessFunctionDAO {

    [OperationContract]
    BusinessFunction GetBusinessFunction(Int32 businessFunctionRefID);

    [OperationContract]
    IEnumerable<Project> GetProjects(Int32 businessFunctionRefID);
}

[ServiceContract]
public partial interface IBusinessUnitDAO {

    [OperationContract]
    BusinessUnit GetBusinessUnit(Int32 businessUnitRefID);

    [OperationContract]
    IEnumerable<Project> GetProjects(Int32 businessUnitRefID);
}
Run Code Online (Sandbox Code Playgroud)

然后,我明确地实现了每个接口.

public class TrackingTool : IBusinessFunctionDAO, IBusinessUnitDAO {

    BusinessFunction IBusinessFunctionDAO.GetBusinessFunction(Int32 businessFunctionRefID) {
      // implementation
    }
    IEnumerable<Project> IBusinessFunctionDAO.GetProjects(Int32 businessFunctionRefID) {
      // implementation
    }

    BusinessUnit IBusinessUnitDAO.GetBusinessUnit(Int32 businessUnitRefID) {
      // implementation
    }
    IEnumerable<Project> IBusinessUnitDAO.GetProjects(Int32 businessUnitRefID) {
      // implementation
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我有两个GetProjects(int)方法,但每个方法都是显式实现的,所以这个编译得很好并且完全有效.当我真正将其作为一项服务开始时,问题就出现了.它给我一个错误,因为TrackingTool已经包含一个定义GetProject.虽然这是真的,但它是不同服务合同的一部分.在生成方法名称时,WCF是否无法区分服务合同?有没有办法让它区分服务合同?

我的App.Config看起来像这样

<service name="TrackingTool">
  <endpoint address="BusinessUnit" contract="IBusinessUnitDAO" />
  <endpoint address="BusinessFunction" contract="IBusinessFunctionDAO" />
</service>
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激.

谢谢,劳尔

Hax*_*lit 10

我想我找到了它的原因.在WSDL中,函数被公开如下:

<wsdl:message name="IBusinessUnitDAO_GetBusinessUnitProjects_InputMessage">
  <wsdl:part name="parameters" element="tns:GetBusinessUnitProjects" />
</wsdl:message>
<wsdl:message name="IBusinessFunctionDAO_GetBusinessFunctionProjects_InputMessage">
  <wsdl:part name="parameters" element="tns:GetBusinessFunctionProjects" />
</wsdl:message>
Run Code Online (Sandbox Code Playgroud)

然后在定义tns:namespace的xsd中,我们有以下内容:

<xs:element name="GetBusinessUnitProjects">
  <xs:complexType>
    <xs:sequence>
      <xs:element minOccurs="0" name="businessUnitRefID" type="xs:int" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="GetBusinessFunctionProjects">
  <xs:complexType>
    <xs:sequence>
      <xs:element minOccurs="0" name="businessFunctionRefID" type="xs:int" />
    </xs:sequence>
  </xs:complexType>
</xs:element>
Run Code Online (Sandbox Code Playgroud)

因此即使服务暴露两个不同的契约,冲突的原因是因为所有wsdl部分元素都在同一名称空间中.因此,当您创建两个相同的函数名时,您将获得具有相同名称的重复元素,从而导致问题.因此,问题的解决方案是为每个服务契约添加名称空间属性.如果我们采取原始服务合同并像这样修改它.

[ServiceContract(Namespace="Tracking/BusinessFunction")]
public partial interface IBusinessFunctionDAO {

    [OperationContract]
    BusinessFunction GetBusinessFunction(Int32 businessFunctionRefID);

    [OperationContract]
    IEnumerable<Project> GetProjects(Int32 businessFunctionRefID);
}

[ServiceContract(Namespace="Tracking/BusinessUnit")]
public partial interface IBusinessUnitDAO {

    [OperationContract]
    BusinessUnit GetBusinessUnit(Int32 businessUnitRefID);

    [OperationContract]
    IEnumerable<Project> GetProjects(Int32 businessUnitRefID);
}
Run Code Online (Sandbox Code Playgroud)

当我们生成WSDL时,我们为每个创建的命名空间获取WSDL.此命名空间的每个端口都标识有其所有操作和元素.因此,在我们的每个单独的WSDL中,我们得到以下内容:

//File: Tracking.BusinessFunction.wsdl
<wsdl:message name="IBusinessFunctionDAO_GetProjects_InputMessage">
  <wsdl:part name="parameters" element="tns:GetProjects" />
</wsdl:message>

//File: Tracking.BusinessUnit.wsdl
<wsdl:message name="IBusinessUnitDAO_GetProjects_InputMessage">
  <wsdl:part name="parameters" element="tns:GetProjects" />
</wsdl:message>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它们都具有相同的元素名称,但由于它们位于不同的名称空间中,因此元素不再相互冲突.如果我们看一下xsd,它们现在已经定义了相同的元素,但具有不同的参数:

//File: Tracking.BusinessFunction.xsd
<xs:element name="GetProjects">
  <xs:complexType>
    <xs:sequence>
      <xs:element minOccurs="0" name="businessFunctionRefID" type="xs:int" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

//File: Tracking.BusinessUnit.xsd
<xs:element name="GetProjects">
  <xs:complexType>
    <xs:sequence>
      <xs:element minOccurs="0" name="businessUnitRefID" type="xs:int" />
    </xs:sequence>
  </xs:complexType>
</xs:element>
Run Code Online (Sandbox Code Playgroud)

因此,我原来的问题的答案是使每个服务契约都存在于一个单独的命名空间中,因此您没有冲突的端口元素.这也使您可以灵活地将合同放在单独的WSDL中,如果要分发它们的一部分,这些WSDL更容易管理.