WCF Несколько контрактов с повторяющимися именами методов - PullRequest
5 голосов
/ 09 марта 2010

У меня есть служба с несколькими контрактами, например, так.

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

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

Мой App.Config выглядит так

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

Любая помощь будет оценена.Raul

Ответы [ 3 ]

10 голосов
/ 10 марта 2010

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

4 голосов
/ 09 марта 2010

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

[OperationContract(Name = "YourMethodNameHere")]<br /> IEnumerable GetProjects(Int32 businessUnitRefID);

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

0 голосов
/ 09 марта 2010

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

[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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...