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

Я затем явно реализовал каждый из интерфейсов как так.

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

Поскольку Вы видите, что у меня есть два GetProjects (интервал) методы, но каждый реализован явно, таким образом, это компилирует очень хорошо и совершенно допустимо. Проблема возникает, когда я на самом деле запускаю это как услуга. Это дает мне ошибку при пребывании, что TrackingTool уже содержит определение GetProject. В то время как это верно, это - часть другого контракта на обслуживание. РАЗВЕ WCF не различает контракты на обслуживание при генерации имен методов? Существует ли способ заставить это различать контракты на обслуживание?

Мое Приложение. Конфигурация похожа на это

<service name="TrackingTool">
  <endpoint address="BusinessUnit" contract="IBusinessUnitDAO" />
  <endpoint address="BusinessFunction" contract="IBusinessFunctionDAO" />
</service>

Любая справка ценилась бы.

Спасибо, Raul

5
задан HaxElit 9 March 2010 в 17:47
поделиться

3 ответа

Я думаю, что нашел причину этого. В 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, которыми легче управлять, если вы распространяете их части.

10
ответ дан 18 December 2019 в 13:13
поделиться

Вы можете попробовать использовать псевдоним:

[OperationContract (Name = "YourMethodNameHere")]
{{ 1}} IEnumerable GetProjects (Int32 businessUnitRefID);

См .: http://jeffbarnes.net/blog/post/2006/09/21/Overloading-Methods-in-WCF.aspx

4
ответ дан 18 December 2019 в 13:13
поделиться

Попробуйте установить свойство Action в атрибуте OperationContract для двух методов, которые имеют одинаковые name, чтобы устранить конфликт, например:

[ServiceContract]
public partial interface IBusinessFunctionDAO {

[OperationContract]
BusinessFunction GetBusinessFunction(Int32 businessFunctionRefID);

[OperationContract(Action="GetBusinessFunctionProjects")]
IEnumerable<Project> GetProjects(Int32 businessFunctionRefID);
}

[ServiceContract]
public partial interface IBusinessUnitDAO {

[OperationContract]
BusinessUnit GetBusinessUnit(Int32 businessUnitRefID);

[OperationContract(Action="GetBusinessUnitProjects")]
IEnumerable<Project> GetProjects(Int32 businessUnitRefID);
}
0
ответ дан 18 December 2019 в 13:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: