2009-12-08 3 views
0

Je crée un service WCF que je souhaite utiliser à partir d'une application Java. Mais la question n'est pas à propos de. Net-java interop.Exportation de schémas WSDL/XSD pour des types de contrat de données avec IXmlSerializable

Le point clé est l'un des types liés à une opération de service est IXmlSerializable. Ce type renvoie son schéma XSD avec la méthode statique référencée par XmlSchemaProviderAttribute. Le problème est lorsque nous obtenons wsdl pour le service via mex-endpoint (http://..svc?wsdl) ce schéma n'est pas retourné.

Voici les détails.

Certains contrat de service WCF:

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    DomainData GetData(); 
} 

Type DomainData est:

[DataContract(Namespace = "http://schemas.biz.org/Samples/customserialization")] 
public class DomainData 
{ 
    [DataMember(Name = "AuxData")] 
    Dictionary<String, AuxDomainData> m_auxData = new Dictionary<string, AuxDomainData>(); 

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

    public IDictionary<string, AuxDomainData> AuxData 
    { 
    get { return m_auxData; } 
    } 
} 

Comme vous pouvez le voir DomainData contient un dictionnaire d'objets AuxDomainData, qui est:

[XmlSchemaProvider("GetXmlSerializationSchema")] 
public class AuxDomainData : IXmlSerializable 
{ 
    [DataMember] 
    public Object AuxData { get; set; } 

    XmlSchema IXmlSerializable.GetSchema() { return null; } 

    void IXmlSerializable.ReadXml(XmlReader reader) { } 

    void IXmlSerializable.WriteXml(XmlWriter writer) { } 

    public static string Namespace = "http://schemas.biz.org/Samples/customserialization"; 

    public static XmlQualifiedName GetXmlSerializationSchema(XmlSchemaSet schemas) 
    { 
    var qname = new XmlQualifiedName("AuxDomainData", Namespace); 
    string resourceName = "CustomSerialization.aux-domain-data.xsd"; 
    using (Stream stream = typeof(AuxDomainData).Assembly.GetManifestResourceStream(resourceName)) 
    { 
    var schema = XmlSchema.Read(stream, null); 
    schemas.Add(schema); 
    } 
    return qname; 
    } 
} 

ici nous retournons le schéma XSD dans la méthode GetXmlSerializationSchema. Le schéma lui-même est simple mais laissez-moi passer ici.

Ce code est simple, je suppose, c'est un scénario courant pour les types IXmlSerializable.

Maintenant, nous voulons WSDL. Je vais utiliser WSDL pour créer un client Java avec l'aide de Metro Mais en réalité JDK 1.6 est suffisant car il contient la pile WS (et wsimport.exe). Alors java veut wsdl avec wsdl: définition de service. C'est pourquoi je ne peux pas lui donner un wsdl de wsdl.exe (parce qu'un wsdl produit par wsdl ne contient pas de définition de service de wsdl, seulement wsdl: portType). Donc, j'appelle wsimport.bat http://localhost/Service1.svc?wsdl

Mais ce que je reçois dans respose est: [ERREUR] undefined type simple ou complexe 'q1: AuxDomainData' ligne 1 de http://locahost/CustomSerialization/Service1.svc?xsd=xsd3

C'est parce qu'un wsdl fait composé ne contient pas de type AuxDomainData. C'est vrai et nous ne pouvons pas blâmer java/metro/tout autre stack. Si nous regardons wsdl produit par WCF il contient wsdl: élément de types avec les importations de tous les schémas XSD:

<wsdl:types> 
    <xsd:schema targetNamespace="http://tempuri.org/Imports"> 
    <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/" /> 
    <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" /> 
    <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd2" namespace="http://schemas.biz.org/Samples/customserialization" /> 
    <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd3" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" /> 
    </xsd:schema> 
</wsdl:types> 

Je ne vais pas » fournir tous xsd ici, mais le point est qu'il n'y a pas définition AuxDomainData dans leur. Le schéma xsd pour le type AuxDomainData se trouve dans http://localhost/CustomSerialization/Service1.svc?xsd=xsd "document". Mais comme vous pouvez le voir, la racine wsdl ne contient pas de référence. C'est le problème. Le résultat du jeu de schémas wsdl/xsd n'est pas complet.

Alors, quelles sont mes options? Etes-vous sûr que le WSDL ne le référence pas?

Répondre

0

Normalement, WCF comprendra un élément juste avant la liste des < wsdl: un message > éléments, un peu comme cela:

<wsdl:types> 
    <xsd:schema targetNamespace="http://tempuri.org/Imports"> 
     <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/"/> 
     <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/> 
     <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/MyServiceNamespace"/> 
     <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/MyServiceNamespace.AnotherNamespace"/> 
     <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd4" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> 
    </xsd:schema> 
</wsdl:types> 

Vérifiez pour cela. Ça devrait être là.Il est toutefois possible que Java ne le reconnaisse pas.

Si tel est le problème, alors il existe des moyens pour flatten the WSDL. Vous pourriez essayer ça. Soit dit en passant, le point de terminaison mex est généralement Service1.svc/mex. WSDL est légèrement différent.

+0

J'ai mentionné à propos de la section types dans le fichier wsdl. Aplatissement wsdl est une idée intéressante, merci. – Shrike

+0

Je pourrais jurer que cette section n'était pas dans le message original. Quoi qu'il en soit, si les importations sont là, alors le problème est que Java ne traite pas les importations. Vous devrez l'aplatir ou changer votre service pour utiliser XmlSerializer (au lieu de DataContractSerializer). – Aaronaught

+0

Exactement, j'ai édité le post plusieurs fois, vous étiez très rapide :). Pardon. Donc, l'aplatissement aide. Merci. – Shrike

0

En fait, la solution proposée par Aaron de "http://blogs.msdn.com/dotnetinterop/archive/2008/09/23/flatten-your-wsdl-with-this-custom-servicehost-for-wcf.aspx" s'avère être pas entièrement correcte. Pas l'idée elle-même, mais le code. Après avoir utilisé ExportExtension pour plusieurs services demandant wsdl pour le service suivant à son tour échoue en raison de la dublication des types. J'ai également demandé sur msdn forum: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/0ea27bec-08cc-4a20-86ce-6e3477abb1c5.

Questions connexes