web-dev-qa-db-fra.com

Quand est-il approprié d'utiliser l'attribut KnownType?

Après avoir lu la référence MSDN, je me pose encore des questions sur le moment d'utiliser l'attribut KnownType. Je comprends que l'attribut communique les informations de type au sérialiseur, mais quand est-ce nécessaire? Est-il approprié que la classe en cours de sérialisation ait des références d'un type de classe de base et qu'il existe des classes dérivées mises à jour pouvant être définies avec ces références?

De plus, y a-t-il des inconvénients à une surutilisation de l'attribut? Par exemple, dans l'exemple précédent, si la classe sérialisée était marquée avec KnownType (baseClass) alors qu'il y avait une référence explicite à ce type?

42
bwerks

[KnownType] est nécessaire pour le dire sur les sous-types. L'inconvénient de pas à l'utiliser est que cela ne fonctionnera pas:

[DataContract]
class Foo {}

[DataContract]
class Bar : Foo {}

avec une méthode sur l'interface WCF qui retourne:

public Foo GetFoo() { return new Bar(); }

Sans l'attribut, le sérialiseur (en particulier pour les types mex/générés par le proxy) ne saura rien à propos de Bar, et il échouera. Avec l'attribut:

[DataContract, KnownType(typeof(Bar))]
class Foo {}

ça va fonctionner. Ceci s'applique uniquement à DataContractSerializer - avec NetDataContractSerializer, vous obtenez les données de type d'une manière différente.

64
Marc Gravell

Si vous utilisez "l'héritage" XSD dans votre schéma. 

Vous l'avez à l'envers; KnownTypeAttribute est appliqué à la classe de base et nomme toutes les classes dérivées pouvant être transmises en tant que référence à la base.

Par exemple:

...
KnownType(typeof(POBoxAddress))
KnownType(typeof(StreetAddress))
KnownType(typeof(SingleLineAddress))
KnownType(typeof(ParsedAddress))
public abstract class AddressBase
{
    ...
}
7
Toby

L'attribut KnownType est nécessaire lorsque vous sérialisez des types non concrets tels que des interfaces ou des classes de base. Le sérialiseur WCF doit connaître toutes les implémentations possibles de l'interface ou de la classe héritée. Toute implémentation dont il ignore l'existence provoquera une exception de sérialisation.

Un usage possible peut être trouvé dans cette SO question

6
chilltemp

Il est également utile dans les cas suivants:

[DataContract]
[knownType(typeof(Person))]
public class KeyValue
{
  [DataMember]
  public string key {get; set;}

  [DataMember]
  public string value {get; set;}

  // rest of the code
}

supposons maintenant que la valeur contienne un objet d'une autre classe, telle que Personne. alors tout cela pour travailler, vous devez ajouter le knownType (typeof (Person))

0
Guruji