Заставить WCF сериализовать неиспользуемый класс

2

Кажется, у меня проблема со следующим фрагментом кода, когда я прихожу к определению того, что такое Item (например, CashInHand), фактический тип CashInHandPayment недоступен, поскольку он не был перенесен, когда я сгенерируйте прокси-класс (скорее всего, потому, что он не читается в XmlElementAttributes).

Есть ли способ заставить классы, такие как AccountPayment, CashInHandPayment и CCPayment, сериализоваться в прокси-классе?

[DataContract]
public class Payment
{
    [XmlElementAttribute("Account", typeof(AccountPayment))]
    [XmlElementAttribute("CashInHand", typeof(CashInHandPayment))]
    [XmlElementAttribute("CreditCard", typeof(CCPayment))]
    [XmlChoiceIdentifierAttribute("ItemElementName")]
    [DataMember]
    public object Item { get; set; }
}

[DataContract]
public enum ItemElementName
{
    [EnumMember]
    Account,
    [EnumMember]
    CashInHand,
    [EnumMember]
    CreditCard
}

//This class will not be in the generated proxy class
[DataContract]
public class AccountPayment
{
    [DataMember]
    public double Amount { get; set; }
}

//classes for CashInHandPayment and CCPayment also created, but not shown.

Простите меня, если "сериализовать" не правильный термин для использования, если вы прочитали вопрос и обнаружили, что это не так, пожалуйста, измените его соответствующим образом.

Обновление - ответ, упомянутый Саймоном Свенссоном:

[KnownType(typeof(AccountPayment))]
[KnownType(typeof(CashInHandPayment))]
[KnownType(typeof(CCPayment))]
[DataContract]
public class Payment
{
    [XmlElementAttribute("Account", typeof(AccountPayment))]
    [XmlElementAttribute("CashInHand", typeof(CashInHandPayment))]
    [XmlElementAttribute("CreditCard", typeof(CCPayment))]
    [XmlChoiceIdentifierAttribute("ItemElementName")]
    [DataMember]
    public object Item { get; set; }
}

Большое спасибо, Саймон!

  • 0
    Привет Дэн :) Саймон, похоже, имеет правильную идею ниже. Атрибут KnownType будет означать, что ваш тип платежа будет разрешен после десериализации.
  • 0
    Привет, Марк! Надеюсь, у тебя все хорошо! Да, KnownType - это то, что я упустил. Его нужно применять не к самому классу, а ко всем классам, которые его используют, что мне кажется немного отсталым!
Теги:
wcf

3 ответа

4
Лучший ответ

Эмм. Isnt XmlElementAttribute и XmlChoiceIdentifierAttribute xml сериализация, которая является более старой сериализацией по сравнению с DataContractSerializer, которая считывает DataContractAttribute и DataMemberAttribute?

Я считаю, что для этого вам следует использовать KnownTypeAttribute, но я никогда не пробовал его, и у меня не было этого сценария в моем собственном коде.

  • 0
    Да, вы правы, это часть более старой сериализации (из оригинального XSD). Чтобы перенести их в прокси-класс, мне пришлось применить KnownType к классу Payment. Большое спасибо!
0

Я думаю, что достаточно указать DataContract. Но если это не работает, почему бы не попытаться создать фиктивный метод OperationContract, который использует класс?

  • 0
    Это было мое последнее прибежище, так как я знал, что это сработает, и я знал, что это невероятно хакерское дело. :) Я согласен с тем, что DataContract должно быть достаточно, но кажется, что если вы создаете сервис, который ссылается на большинство используемых вами классов, то при создании прокси он оставляет неиспользуемые, даже если вы применяете DataContract ко всем из них.
0

Есть ли способ заставить классы, такие как AccountPayment,   CashInHandPayment и CCPayment должны быть сериализованы в прокси-классе?

Они должны быть отмечены атрибутом [DataContract], которого должно быть достаточно, я бы подумал.

Когда svcutil.exe (либо запущенный непосредственно из командной строки, либо из Visual Studio с помощью Add Service Reference) встречает классы с атрибутом [DataContract] для класса и [DataMember] для свойств (или полей), он будет создайте копию в прокси для этих классов.

Марк

  • 0
    Marc, как показано в коде с AccountPayment в качестве примера, классы имеют набор DataContractAttribute.
  • 0
    Хорошо - хорошо, вы уже получили свой идеальный ответ, кажется!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню