2012-10-22 2 views
1

J'ai un DataMember (isRequired: = True) que cette propriété est appelée FillerInd. Maintenant, comment dites-vous si ce champ est vide ou n'existe pas? Je lisais en ligne et vous devez faire une sérialisation et une désérialisation de XML si le champ est manquant, il va lancer l'exception MissingMethodException. Je n'ai aucune idée de la façon de mettre en œuvre ceci ou si c'est la meilleure voie à prendre. Toute aide pour me mettre dans la bonne voie, je l'apprécierais vraiment.Comment vérifier si le champ isRequired a la valeur true dans WCF

Répondre

4

La propriété DataMember IsRequired vous indique si la propriété est requise sur le fil: s'il doit être présent dans le message ou non. Une situation typique où cela entraînerait des exceptions est lorsque le service met à jour le DataContract en ajoutant une propriété avec IsRequired = true, sans avertir les clients. Les clients enverront des objets sérialisés qui n'incluent pas la propriété, entraînant l'émission d'une exception.

Une situation moins courante, mais un moyen facile de reproduire ce problème à l'aide d'une propriété de type basique consiste à définir explicitement la propriété EmitDefaultValue sur false. Si vous faites cela, puis essayez d'appeler une opération avec un objet de ce DataContract, une exception peut être levée. Considérez cet exemple:

// Data Contract 
[DataContract] 
public class Animal 
{ 
    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    public string Name; 
} 

// IService 
[OperationContract] 
int GetIdentifier(Animal animal); 

// Client operation 
int id = client.GetIdentifier(new Animal()); // Causes exception 

Cela entraînera un SerializationException (provoquant à son tour une CommunicationException) avec un message dans ce sens:

Nom du membre dans le type .... animal ne peut pas être publié en feuilleton. Cette exception est généralement provoquée en essayant d'utiliser une valeur nulle où une valeur nulle n'est pas autorisée. Le membre 'Name' est défini sur sa valeur par défaut (généralement null ou zéro). Le paramètre EmitDefault du membre est 'false', indiquant que le membre ne doit pas être sérialisé. Toutefois, le paramètre IsRequired du membre est 'true', indiquant qu'il doit être sérialisé. Ce conflit ne peut pas être résolu. Envisagez de définir 'Name' sur une valeur autre que par défaut. Vous pouvez également remplacer la propriété EmitDefaultValue de l'attribut DataMemberAttribute par true ou modifier la propriété IsRequired par false.

Notez que si vous contourner ce problème côté client (par exemple en modifiant les reference.cs pour une référence de service généré afin que le DataMember n'est plus nécessaire sur le côté client), le service rencontrera une exception lorsque désérialiser, ce qui va causer une faute, je crois.


Passant à vos remarques et questions spécifiques.

Vous n'avez rien à dire si le champ est vide: le framework WCF gère cela pour vous. Si nécessaire, je suppose que vous pourriez vous connecter à la (dé) sérialisation pour avoir la tête haute sur ce problème, ou même inspecter le message avant qu'il ne soit manipulé.

Comme je l'ai dit, cette situation provoquera SerializationExceptions et CommunicationExceptions, pas un MissingMethodException.

Que vous ayez besoin de "IsRequired" et que ce soit la "meilleure route à prendre", je ne saurais pas. Cela dépend de votre situation, bien sûr.

+0

Donc, si je comprends bien et que l'on utilise une classe comme paramètre pour une méthode et qu'un client appellera cette méthode, une exception sera émise lors de l'envoi? Ou est-ce que je comprends mal le 'EmitDefaultValue'? – Silvermind

+1

Oui, c'est ce qui se passe. Clafiry: un client * WCF * lancera une exception si vous essayez d'envoyer (et donc de sérialiser) un objet où une propriété requise n'est pas définie et EmitDefaultValue est false.Si vous avez un client qui contourne ceci, le * service * lancera une exception lors de la désérialisation. – Jeroen

+0

Je viens de le tester, mais ce n'est pas tout à fait vrai (pas d'infraction). Il lèvera une exception si elle est définie sur la valeur par défaut. Si je marque un booléen avec 'Required = true, EmitDefaultValue = false' et que je mets ce booléen explicitement du côté client à' false', il lèvera quand même une exception. C'est logique bien sûr. Il n'y aurait aucun moyen pour le service de savoir si la propriété est vraiment définie sans état triplé. Pour les types de valeur, je peux m'en tenir à 'Nullable ' dans ce cas et pour les chaînes et les classes, je pourrais faire une différence entre 'String.Empty' et' null'. Merci, c'est vraiment utile. – Silvermind

Questions connexes