skyfrog
skyfrog

Reputation: 117

WCF Web Service: How to return an inherited object that is known on the client

I have an object AddressDTO that inherits from ResponseDTO.

[DataContract]
public class ResponseDTO
{
   [DataMember]
   public string ID {get; set;}
}
[DataContract]    
public class AddressDTO : ResponseDTO
{
   [DataMember]
   public List<Address> Elements {get; set;}
}

I'd like to have a kind of generic Web Service that receives a RequestDTO as an input parameter and creates (depending on the RequestType in the RequestDTO) either an AddressDTO or a ResponseDTO.

public ResponseDTO GetDataFromWebService(RequestDTO request)
{
   ...
   ResponseDTO response = null;
   switch(request.Request)
   {
      case RequestType.Case1:
         response = new AddressDTO();
         break;
      case RequestType.Case2:
      default:
         response = new ResponseDTO();
         break;
   }
   ...
   return response;
}

On the client side, when trying to consume this Web Service, I'll receive an object ResponseDTO even I have sent an AddressDTO over the wire (Case1). I cannot cast to AddressDTO since AddressDTO is not known on the client (through the WSDL definition) as an object and therefore the property Elements with a list of Address objects is hidden (or not exported/transferred) to the client.

Is this not possible to deal with inheritance on Web Services the way I've tried or do I have to declare the inheritance somehow for the WSDL so that the client is able to rebuild the inherited structure so that I could cast the ResponseDTO to an AddressDTO at the end of the day?

Many thanks for your answers/ideas in advance.

Upvotes: 1

Views: 1520

Answers (2)

vikrantx
vikrantx

Reputation: 603

Here is a small demo of known type..
Following service is tested on WCF Test Client.
In wcf test client, you will get different output for you inputs (Request1 ,Request2).

IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfKnownTypeStackOverFlow
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        ResponseDTO GetDataFromWebService(RequestDTO request);
    }

    [DataContract]
    [KnownType(typeof(AddressDTO))]
    public class ResponseDTO
    {
        [DataMember]
        public string ID { get; set; }
    }

    [DataContract]
    public class AddressDTO : ResponseDTO
    {
        [DataMember]
        public List<Address> Elements { get; set; }
    }

    [DataContract]
    public class Address
    {
        [DataMember]
        public string Street { get; set; }

        [DataMember]
        public string City { get; set; }
    }

    [DataContract]
    public enum RequestDTO
    {
        [EnumMember]
        Request1,

        [EnumMember]
        Request2
    }
}

Service1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfKnownTypeStackOverFlow
{
    public class Service1 : IService1
    {
     public ResponseDTO GetDataFromWebService(RequestDTO request)
     {
           ResponseDTO response = null;
           switch(request)
           {
               case RequestDTO.Request1:
                   {
                       AddressDTO addrDto = new AddressDTO();
                       Address addr = new Address();
                       addrDto.Elements = new List<Address>() 
                       { 
                           new Address                          
                           { 
                               City ="mycity", 
                               Street="mystreet"}, 
                           new Address
                           {
                               City="yourcity", 
                               Street="yourcity"}};

                       response =  (ResponseDTO)addrDto;
                       break;
                   }
              case RequestDTO.Request2:
               default:
                  {
                     response = new ResponseDTO();
                     response.ID = "responseDto";
                     break;
                 }
           }
           return response;
        }
    }
}

Output for Request1

enter image description here

Output for Request2

enter image description here

Upvotes: 1

skyfrog
skyfrog

Reputation: 117

Thanks vikrantx for the hint of the KnownType. - I didn't know!

The following link to code project will explain the topic in more detail.

I guess, this will solve my question even I couldn't try it out so far.

Upvotes: 1

Related Questions