Я разрабатываю службу WCF. Методы, которые должна поддерживать эта служба, определяются третьей стороной. Интерфейс, определяющий сервисный контракт, частично выглядит так:
[SoapHeaders]
[ServiceContract(Namespace = "abc.xyz")]
public interface IAbcSoap
{
[SoapHeader("AuthenticationHeader",
typeof(AuthenticationHeader),
Direction = SoapHeaderDirection.In)]
[OperationContract(Action = "abc.xyz/ReverseCard")]
ReverseCardResponse ReverseCard(
OriginalRequest OriginalRequest);
Классы, определяющие контракт данных, включают OriginalRequest и несколько более конкретных типов, которые наследуются от OriginalRequest, например:
[DataContract]
public class OriginalRequest
{
[DataMember]
public MessageHeader MsgHeader { get; set; }
}
[DataContract]
public class OriginalLoadRequest : OriginalRequest
{
[DataMember]
public long ProductCode { get; set; }
}
У меня есть тестовая клиентская программа, созданная с помощью SvcUtil из WSDL, сгенерированного службой. Моя проблема в том, что код, сгенерированный из WSDL, включает только OriginalRequest, а не классы, такие как OriginalLoadRequest, которые наследуются от OriginalRequest, предположительно потому, что в интерфейсе нет ссылки на эти классы. Я попытался добавить перегрузку интерфейса следующим образом:
[OperationContract(Action = "abc.xyz/ReverseCard")]
ReverseCardResponse ReverseCard(
OriginalRequest OriginalLoadRequest);
Но это вызывает ошибку при попытке создать WSDL. Если я правильно понимаю, это потому, что у меня не может быть двух методов с одним и тем же действием. Но действие определяется третьей стороной. Я не могу это изменить.
Что я могу сделать, чтобы клиентская программа знала об OriginalLoadRequest и других классах, наследуемых от OriginalRequest?
В твоей перегрузке,
[OperationContract(Action = "abc.xyz/ReverseCard")]
ReverseCardResponse ReverseCard(
OriginalRequest OriginalLoadRequest);
разве вы не перепутали тип и имя параметра, т.е. не должно быть
OriginalLoadRequest OriginalRequest);
или даже
OriginalLoadRequest OriginalLoadRequest);
Я считаю, что нашел ответ. Похоже, мне нужен был атрибут KnownType:
[DataContract]
[KnownType(typeof(OriginalConfirmRequest))]
[KnownType(typeof(OriginalLoadRequest))]
[KnownType(typeof(OriginalRedeemRequest))]
[KnownType(typeof(OriginalVoidRequest))]
public class OriginalRequest
{
[DataMember]
public MessageHeader MsgHeader { get; set; }
}
Этот похожий вопрос помог: Как вернуть список <объект> в WCF
Да, спасибо, я думаю, вы правы. Однако, если я правильно понимаю, я не думаю, что в любом случае мог бы использовать перегрузку, поскольку я не думаю, что у меня может быть два метода, реализующих одно и то же действие. Использование атрибута KnownType, похоже, исправило это. Но спасибо, что нашли время, чтобы попытаться помочь.