Почему поля базового класса не сериализуются при возврате объекта производного класса из веб-метода ASMX? - PullRequest
5 голосов
/ 28 февраля 2011

У меня есть два класса и веб-метод следующим образом

[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 ]

3 голосов
/ 28 февраля 2011

Вы можете удалить атрибуты [Serializable] из ваших классов, это должно работать без. POCO не требуют присутствия атрибута, они отлично сериализуются, как они есть.

Редактировать : Вы действительно проверили, что такое вывод веб-службы, или вы просто просматриваете определение сообщения в конечной точке веб-службы?

Я вижу, что формат сообщения 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 , класс сериализуется:

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

Диалоговое окно Visual Studio «Добавить веб-ссылку» также правильно создает прокси-классы.

Редактировать 2 : Глядя на сгенерированное для нас определение веб-сервиса (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 голос
/ 28 февраля 2011

Вы должны добавить атрибут KnownType в базовый класс.

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