Я думаю, что нашел причину для этого. В 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>
Тогда в xsd, который определяет пространство имен tns:, мы имеем следующее:
<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>
Таким образом, причина конфликта, даже несмотря на то, что служба предоставляет два разных контракта, заключается в том, что все элементы детали 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);
}
Когда мы генерируем 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>
как вы можете видеть, они оба имеют одинаковое имя элемента, но поскольку они находятся в разных пространствах имен, элементы больше не конфликтуют друг с другом. Если мы посмотрим на 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>
Таким образом, ответ на мой первоначальный вопрос заключается в том, чтобы каждый контракт на обслуживание работал в отдельном пространстве имен, чтобы у вас не было конфликтующих элементов порта. Это также дает вам гибкость при наличии ваших контрактов в отдельных WSDL, которыми легче управлять, если вы распространяете их части.