WCF Web服务:如何返回客户端上已知的继承对象

时间:2015-02-13 07:08:18

标签: c# web-services wcf inheritance wsdl

我有一个继承自ResponseDTO的对象AddressDTO。

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

我希望有一种通用的Web服务,它接收RequestDTO作为输入参数,并创建(取决于RequestDTO中的RequestType)AddressDTO或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;
}

在客户端,当尝试使用此Web服务时,我将收到一个对象ResponseDTO,即使我已经通过线路发送了AddressDTO(Case1)。我无法转换为AddressDTO,因为AddressDTO在客户端(通过WSDL定义)不知道作为对象,因此具有Address对象列表的属性Elements被隐藏(或不导出/传输)到客户端。

这是不可能以我尝试过的方式处理Web服务上的继承,或者我必须以某种方式为WSDL声明继承,以便客户端能够重建继承的结构,以便我可以转换ResponseDTO在一天结束时到一个地址DTO?

非常感谢你的答案/想法。

2 个答案:

答案 0 :(得分:1)

感谢vikrantx提供KnownType的提示。 - 我不知道!

以下link代码项目将更详细地解释该主题。

我想,这将解决我的问题,即使到目前为止我也无法尝试。

答案 1 :(得分:1)

这是一个已知类型的小型演示..
以下服务在WCF测试客户端上进行测试 在wcf测试客户端中,您将获得输入的不同输出(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;
        }
    }
}

Request1的输出

enter image description here

Request2的输出

enter image description here