从ASMX Web方法返回派生类对象时,为什么我的基类字段没有被序列化?

时间:2011-02-28 19:30:29

标签: c# web-services asmx

我有两个类和一个web方法如下

[Serializable]
public class BaseClass
{
    public int  Key;
    public bool IsModified;
    public bool IsNew;
    public bool IsDeleted;
}

[Serializable]
public class DerivedClass : BaseClass
{
    public string Name;
}

[WebMethod]
public List<DerivedClass> GetDerivedClassObjects()
{

}

但是当我看到SOAP响应时,我没有看到基类中的字段。它们不应该被序列化吗?如果我想要将它们序列化应该做什么?

2 个答案:

答案 0 :(得分:3)

您可以从类中删除[Serializable]属性,这应该可以不用。 POCO不需要存在属性,它们按原样序列化。

编辑:您是否实际检查了Web服务输出是什么,或者您只是查看服务Web端点上的消息定义?

我可以看到浏览浏览器中的服务端点时生成的SOAP消息格式似乎对基类字段一无所知:

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetDerivedClassObjectsResponse xmlns="http://tempuri.org/">
      <GetDerivedClassObjectsResult>
        <DerivedClass>
          <Name>string</Name>
        </DerivedClass>
        <DerivedClass>
          <Name>string</Name>
        </DerivedClass>
      </GetDerivedClassObjectsResult>
    </GetDerivedClassObjectsResponse>
  </soap:Body>
</soap:Envelope>

但是当您使用测试表单或Storm调用Web服务时,该类将被序列化:

<DerivedClass>
    <Key>1</Key> 
    <IsModified>true</IsModified> 
    <IsNew>true</IsNew> 
    <IsDeleted>true</IsDeleted> 
    <Name>Test1</Name> 
</DerivedClass>

visual studio“添加Web引用”对话框也可以正确创建代理类。

编辑2 :查看为我们生成的Web服务定义(service.asmx?wsdl),我们可以看到该定义保留了原始继承层次结构,而不是将对象展平为它在序列化过程中的字段:

<s:complexType name="DerivedClass">
    <s:complexContent mixed="false">
        <s:extension base="tns:BaseClass">
            <s:sequence>
                <s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" /> 
            </s:sequence>
        </s:extension>
    </s:complexContent>
</s:complexType>
<s:complexType name="BaseClass">
    <s:sequence>
        <s:element minOccurs="1" maxOccurs="1" name="Key" type="s:int" /> 
        <s:element minOccurs="1" maxOccurs="1" name="IsModified" type="s:boolean" /> 
        <s:element minOccurs="1" maxOccurs="1" name="IsNew" type="s:boolean" /> 
        <s:element minOccurs="1" maxOccurs="1" name="IsDeleted" type="s:boolean" /> 
    </s:sequence>
</s:complexType>

有趣的是,似乎服务端点上生成的示例消息不考虑扩展。但是对于所有其他效果和目的,您的代码应该工作。

答案 1 :(得分:1)

您必须将KnownType属性添加到基类。

[Serializable]
[KnownType(typeof(DerivedClass )]
public class BaseClass
{
   ...
}