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

log*_*ik6 5 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()
{

}
Run Code Online (Sandbox Code Playgroud)

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

jev*_*lio 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>
Run Code Online (Sandbox Code Playgroud)

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

<DerivedClass>
    <Key>1</Key> 
    <IsModified>true</IsModified> 
    <IsNew>true</IsNew> 
    <IsDeleted>true</IsDeleted> 
    <Name>Test1</Name> 
</DerivedClass>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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