Сложные ситуации, связанные с DataContract в WCF - PullRequest
1 голос
/ 31 мая 2011

Существуют тысячи вопросов, касающихся DataContract (s) в WCF, с особым вниманием к тем ситуациям, когда происходит наследование.Однако я не нашел никаких примеров, относящихся к конкретным ситуациям, которые все суммированы в той, которую я собираюсь предоставить здесь.

Рассмотрим следующее DataContract, примененное к типу, используемому в связи службы WCF (листинг кода1) :

// Data contract for my comm type
[DataContract]
public class MyCommsType {
   [DataMember]
   public Type1 field1;
   [DataMember]
   public Type2 field2;
   [DataMember]
   public Type1 field3;
   [DataMember]
   public Type2 field4;
   [DataMember]
   public List<Type2> field5;
   [DataMember]
   public List<Type1> field6;
}
// Used types
public class Type1 {
   ...
}
public class Type2 {
   ...
}

Этот тип должен использоваться здесь (Листинг 1.1) :

[ServiceContract]
public interface IMyService {
   [OperationContract]
   string CommOp1(MyCommType mct);
   [OperationContract]
   MyCommType CommOp2(string s);
}

Мой личный тип MyCommsTypeэто тип, участвующий в коммуникациях.Но, конечно, CLR не знает, как его сериализовать, поскольку он не является нативным типом в библиотеке базовых классов.Для MyCommsType нужен договор на данные, и я его предоставил.Однако этого состояния недостаточно для того, чтобы все заработало (ничто не работает так!).

Почему это не работает?Это потому, что внутри моего MyCommsType есть неизвестные типы?

Хорошо, я должен сделать следующее (листинг 2) ?

// Data contract for my comm type
[DataContract]
[KnownType(typeof(Type1))]
[KnownType(typeof(Type2))]
[KnownType(typeof(List<Type1>))]
[KnownType(typeof(List<Type2>))]
public class MyCommsType {
   [DataMember]
   public Type1 field1;
   [DataMember]
   public Type2 field2;
   [DataMember]
   public Type1 field3;
   [DataMember]
   public Type2 field4;
   [DataMember]
   public List<Type2> field5;
   [DataMember]
   public List<Type1> field6;
}

Это так?правильный ????

Однако, если он правильный, как CLR знает, как сериализовать Type1 и Type2 ?????Я никогда не добавлял атрибут к этим двум типам ????Нужно ли ставить [Serializable], как показано здесь (листинг 3) ?

// Used types
[Serializable]
public class Type1 {
   ...
}
[Serializable]
public class Type2 {
   ...
}

Как справиться с этой ситуацией?

Чтобы сделать ее проще (для ответа) рассмотрите следующие вопросы:

1) Решает ли Перечисление кодов 1 полностью проблемы с сериализацией?

1a) Если нет, то как бороться спроблема?

2) В случае 1) нормально, как бороться с проблемами сериализации Type1 и Type2?Решает ли [Serializable] приложение?

1 Ответ

4 голосов
/ 31 мая 2011

Ваша проблема может быть решена намного проще.

Независимо от того, какой тип вы используете, все, что вам нужно сделать, это просто сделать его сериализуемым. Более простое решение - сделать ваши подклассы самими данными.

Например, если у вас есть

// Data contract for my comm type  
[DataContract]  
public class MyCommsType {     
[DataMember]     public Type1 field1;     
[DataMember]     public Type2 field2;     
[DataMember]     public Type1 field3;     
[DataMember]     public Type2 field4;     
[DataMember]     public List<Type2> field5;     
[DataMember]     public List<Type1> field6;  
}  

Убедитесь, что Type1 и Type2 являются Datacontracts. Это все, что вам нужно сделать.

[DataContract]
public class Type1 {...}

[DataContract]
public class Type2 {...}

Если вы выполняете Inherence любого типа, вам может потребоваться разместить атрибут KnownType. В противном случае достаточно сохранить подтипы (Type1 и Type2), как это делает Datacontracts.

...