0

I am developing a WCF service. The methods that this service must support are defined by a third party. The interface that defines the service contract looks, in part, like this:

[SoapHeaders]
[ServiceContract(Namespace ="abc.xyz")]
public interface IAbcSoap
{
    [SoapHeader("AuthenticationHeader", 
        typeof(AuthenticationHeader), 
        Direction = SoapHeaderDirection.In)]
    [OperationContract(Action = "abc.xyz/ReverseCard")]
    ReverseCardResponse ReverseCard(
        OriginalRequest OriginalRequest);

The classes that define the data contract include an OriginalRequest and several more specific types that inherit from OriginalRequest, like so:

[DataContract]
public class OriginalRequest
{
    [DataMember]
    public MessageHeader MsgHeader { get; set; }
}

[DataContract]
public class OriginalLoadRequest : OriginalRequest
{
    [DataMember]
    public long ProductCode { get; set; }
}

I have a test client program, created using SvcUtil from the WSDL generated by the service. My problem is that the code generated from the WSDL includes only the OriginalRequest, not the classes like OriginalLoadRequest that inherit from OriginalRequest, presumably because there is no reference to these classes in the interface. I tried adding an overload to the interface like so:

[OperationContract(Action = "abc.xyz/ReverseCard")]
ReverseCardResponse ReverseCard(
    OriginalRequest OriginalLoadRequest);

But this causes an error when trying to generate the WSDL. If I understand correctly this is because I cannot have two methods with the same action. But the action is defined by the third party. I can't change that.

What can I do to make the client program aware of the OriginalLoadRequest and other classes that inherit from OriginalRequest?

Brendan Reynolds
  • 991
  • 2
  • 9
  • 19

2 Answers2

0

In your overload,

[OperationContract(Action = "abc.xyz/ReverseCard")]
ReverseCardResponse ReverseCard(
    OriginalRequest OriginalLoadRequest);

haven't you got the parameter type and name the wrong way round, i.e. shouldn't it be

OriginalLoadRequest OriginalRequest);

or even

OriginalLoadRequest OriginalLoadRequest);
spodger
  • 1,668
  • 1
  • 12
  • 16
  • Yes, thank you, I believe you're right about that. However, if I understand correctly, I don't think I could have used the overload anyway, as I don't think I can have two methods that implement the same action. Using the KnownType attribute seems to have fixed it. But thank your for taking the time to try to help. – Brendan Reynolds Mar 12 '19 at 13:45
0

I believe I've found the answer. It looks like what I needed was the KnownType attribute:

[DataContract]
[KnownType(typeof(OriginalConfirmRequest))]
[KnownType(typeof(OriginalLoadRequest))]
[KnownType(typeof(OriginalRedeemRequest))]
[KnownType(typeof(OriginalVoidRequest))]
public class OriginalRequest
{
    [DataMember]
    public MessageHeader MsgHeader { get; set; }
}

This similar question helped: How to return a List<object> in WCF

Brendan Reynolds
  • 991
  • 2
  • 9
  • 19