2008-11-06 7 views
0

Je suis en train de créer une implémentation WSTransfer (je réalise baiser Roman a écrit un déjà WCF - mais il ne répond pas vraiment aux spécifications)Création de messages WCF avec mutiple namespaces

J'ai fini par abandonner contrats de données sur les contacts de service car WSTransfer est faiblement couplé; donc chaque message de création ressemble à Message Create (demande de message).

Cela fonctionne bien, et tout est charmant jusqu'à ce qu'il soit temps de renvoyer une réponse.

Le problème que j'ai est dans la façon dont une réponse WSTransfer est construite. Prenant create comme exemple, la réponse ressemble à

<wxf:ResourceCreated> 
    <wsa:Address>....</wsa:Address> 
    <wsa:ReferenceProperties> 
    <xxx:MyID>....</xxx:MyId> 
    </wsa:ReferenceProperties> 
</wxf:ResourceCreated> 

Comme vous pouvez le voir, il y a 3 espaces de noms XML différents dans le message de réponse.

Maintenant, c'est assez facile quand on est impliqué; vous pouvez (même si vous n'êtes pas l'exposer), créer un contrat de données et définir les valeurs et le feu en arrière

Message response = Message.CreateMessage(request.Version, 
      "http://schemas.xmlsoap.org/ws/2004/09/transfer/CreateResponse", 
      resourceCreatedMessage); 

Cependant, le problème se pose dans la mise en espaces de noms différents pour les éléments enfants dans la réponse; il semble que les contrats de données de WCF ne le font pas. Même en utilisant les éléments individuels au sein de la classe de réponse

[MessageBodyMember(Namespace="....")] 

ne semblent pas apporter des modifications, tout devient une partie de l'espace de noms spécifié pour la classe de contrat.

Comment appliquer différents espaces de noms à des éléments individuels dans un message WCF? soit par un contrat, ou par l'intermédiaire d'une autre pokery jiggery?

Répondre

0

Alors suite à la réponse de jezell; le problème avec l'utilisation de XmlSerialization lors de la création d'un message à la main est que les éléments enfants de la racine obtiennent leurs noms d'éléments mutilés. Cela se produit car, bien que le contrat d'opération soit marqué comme [XmlSerializerFormat] lorsque vous créez un message à la main, DataContractSerializer est utilisé.

Vous ne pouvez pas passer le XmlSerializer dans Message.CreateMessage() car il requiert un XmlObjectSerializer, ce qui n'est pas le cas de XmlSerializer. La réponse semble être écrire une classe wrapper pour XmlSerializer, qui a XmlObjectSerializer comme sa classe de base (here's an example) et transmettre cela dans; avec votre message en tenant classe.

Malheureusement, il n'est pas assez intelligent pour configurer les préfixes dans le XML; si vous vous retrouvez avec des messages comme

<ResourceCreated xmlns="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Address xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing/">http://localhost:8731/Design_Time_Addresses/AddTests/WSTransfer/</Address> 
    <ReferenceType xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing/"></ReferenceType> 

Mais il est tout équivalent.

0

Dans un cas comme celui-ci, lorsque vous avez besoin d'un contrôle précis sur la sortie XML, vous devez utiliser le XmlSerializer au lieu de la sérialisation DataContract ou MessageContract. Voici plus d'informations sur la façon de le faire:

http://msdn.microsoft.com/en-us/library/ms733901.aspx

+0

Été là, essayé cela; qui échoue encore plus horriblement :) – blowdart

+0

Qu'est-ce qui ne fonctionnait pas pour vous? – jezell

Questions connexes