locked
Help on using ServiceDescription with WSDLs that contain import directives RRS feed

  • Question

  • User-853754890 posted

    Hi!

    I've been trying to import a .wsdl that imports schemas (e.g. if you have a webmethod that contains a custom dataset), and I find out that when I load the .wsdl file, the imports are not resolved/imported.

    Is there any way for me resolve these imports in a easy way (e.g. when loading an XML with ext. refs. I can customize an XmlResolver...), or must I run through the Imports collections and solve one by one after loading the WSDL?

    Thanks in advance

    jmn

    Sunday, April 15, 2007 6:57 AM

All replies

  • User552765832 posted

    Hi,

     I don't really understand your situation:

    • What do you mean with 'import'? Is that the same as adding a web reference?
    • What do you mean with 'run through the Imports collections'? Do you attempt to re-work the default Reference.cs on the client side?

    But may be this could help you:

    If you have a [webMethod] returning an object of type Dataset, the type 'Dataset' will not be included in the wsdl (normal, it's part of the framwork definition). But if the [WebMethod] returns a 'typed-dataset', it's schema will be included.

     

    Arbiorix

    Tuesday, April 17, 2007 8:28 AM
  • User-853754890 posted

    Ok... let me give you a concrete example, so it may be clear:

    The main WSDL is something like:

    1    <?xml version="1.0" encoding="utf-8"?>
    2    <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="urn://pragmasis.pt/services" xmlns:s1="http://microsoft.com/wsdl/types/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="urn://pragmasis.pt/services" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    3      <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Sample service</wsdl:documentation>
    4      <wsdl:import namespace="urn://pragmasis.pt/services" location="file://C:/defs.wsdl" />
    5      <wsdl:message name="AverageSoapIn">
    6        <wsdl:part name="parameters" element="tns:Average" />
    7      </wsdl:message>
    ...
    122  </wsdl:definitions>
     The defs.wsdl :
     
    1    <?xml version="1.0" encoding="utf-8"?>
    2    <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="urn://pragmasis.pt/services" xmlns:s1="http://microsoft.com/wsdl/types/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="urn://pragmasis.pt/services" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    3      <wsdl:types>
    4        <s:schema elementFormDefault="qualified" targetNamespace="urn://pragmasis.pt/services">
    5          <s:import namespace="http://tempuri.org/RDS.xsd" />
    6          <s:import namespace="http://microsoft.com/wsdl/types/" />
    7          <s:import schemaLocation="file://C:/rds.xsd" namespace="http://tempuri.org/RDS.xsd" />
    8          <s:element name="Average">
    ...
    92   </wsdl:definitions>
    
    And finally, the RDS.XSD is:
     
    1    <?xml version="1.0" encoding="utf-8"?>
    2    <xs:schema xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:mstns="http://tempuri.org/RDS.xsd" xmlns="http://tempuri.org/RDS.xsd" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://tempuri.org/RDS.xsd" id="RDS" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    3      <xs:element msdata:IsDataSet="true" msdata:UseCurrentLocale="true" name="RDS">
    4        <xs:complexType>
    5          <xs:choice minOccurs="0" maxOccurs="unbounded">
    6            <xs:element name="MOVs">
    7              <xs:complexType>
    8                <xs:sequence>
    9                  <xs:element minOccurs="0" name="Date" type="xs:dateTime" />
    10                 <xs:element minOccurs="0" name="Description" type="xs:string" />
    11                 <xs:element minOccurs="0" name="Amount" type="xs:decimal" />
    12               </xs:sequence>
    13             </xs:complexType>
    14           </xs:element>
    15         </xs:choice>
    16       </xs:complexType>
    17     </xs:element>
    18   </xs:schema>
    
     

     If I use the ServiceDescription, the wsdl:import and s:import tags, on the service.wsdl and defs.wsld are not resolved by default. These are the 'imports' that I would like to resolve, without the need of iteration through the ServiceDescription.Imports and ServiceDescription.Types.Schemas[i].Includes collections!

     

    Tuesday, April 17, 2007 6:14 PM
  • User552765832 posted

    Thank you for the informations.

    I think I still miss the context. How did you create the web-service? How  do you get the error? At which stage?

    In the mean time, I have compared your files with what I usually uses.

    For the sample, in Visual Studio 2005, I have created a web service with one method returning a simple typed dataset (1 Table, 1 Column).

    Browsing to the site?WSDL, I get the following:

    <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
      <wsdl:types>
        <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
          <s:import namespace="http://tempuri.org/DataSet1.xsd" />
          <s:import schemaLocation="http://localhost:1371/WebSite1/Service.asmx?schema=DataSet1" namespace="http://tempuri.org/DataSet1.xsd" />
          <s:element name="HelloWorld">
            <s:complexType />
          </s:element>
          <s:element name="HelloWorldResponse">
            <s:complexType>
              <s:sequence>
                <s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult">
                  <s:complexType>
                    <s:sequence>
                      <s:any namespace="http://tempuri.org/DataSet1.xsd" />
                    </s:sequence>
                  </s:complexType>
     

     

    Comparing this result to what you have, I notice that

    1. I have <s:import namespace="http://tempuri.org/DataSet1.xsd" />
      when you have <wsdl:import namespace="urn://pragmasis.pt/services" location="file://C:/defs.wsdl" />
    2. I have <s:import schemaLocation="http:// while you don't have any.

     As you said that you have problems at <wsdl:import namespace=..., this is may be the first place where to search.

     

    Hope this help

    Wednesday, April 18, 2007 4:25 AM
  • User-853754890 posted

    If the WSDL is a .NET generated one... I almost have no problem...

    Almost because if you try to compile the proxy generated by the ServiceDescriptionImporter, it will fail, saying that it can't find the DataSet1!

    That's where my problem started! So, I find out that I need to retrieve the schema "by hand" and add it to the importer so the generated assembly looks fine!

    Additionaly, my customer came to me saying that "accordingly to the WSDL specs", a WSDL file can import another one... that's where my first import with "location" came from -- each imported WSDL will appear on the Imports collection from the ServiceDescription class.

    Since I'm not the one generating the WSDLs... I would like to ensure that I stick to the definition...


    Wednesday, April 18, 2007 8:15 AM
  • User552765832 posted

    I am sorry, but it sounds like your situation goes behind my capacities :-(

    I never had to work with a custom wsdl using imports.

    So, if anybody else could help...

    Wednesday, April 18, 2007 8:23 AM
  • User-853754890 posted

    Thanks for your attention [:)]

    jmn 

    Wednesday, April 18, 2007 8:43 AM
  • User-1034548138 posted

    How are you trying to import the WSDL?  Are you using the ServiceDescription class to then generate a proxy using the CodeCompiler?

    Thursday, May 31, 2007 5:42 AM
  • User634351653 posted

    I have a stream to retrieve it, which I pass to the ServiceDescription class; then, with the ServiceDescriptionImporter  I create the CodeCompileUnit, but when i try to compile it, I receive an error about the missing types -- which are referenced on the original WSDL import section, but are not imported at all...

    I also tried to manually import them -- by retrieving their schemas and add them manually -- and this time it work!

     

    Monday, June 4, 2007 3:51 AM
  • User-1034548138 posted

    I had the exact same problem.  Here's a code snippet to dynamically discover the included xsd schemas

                WebClient client = null;
                Stream wsdlStream = null;
                client = new WebClient();
                string[] referenceAssemblies = new string[] {"system.dll", "System.Xml.dll", "System.Web.Services.dll"};
                wsdlStream = client.OpenRead(wsdlURI);

                ServiceDescription wsdl = ServiceDescription.Read(wsdlStream);
               
                ServiceDescriptionImporter wsdlImport = new ServiceDescriptionImporter();
                wsdlImport.AddServiceDescription(wsdl, null, null);

                // Add any imported files
                foreach (System.Xml.Schema.XmlSchema wsdlSchema in wsdl.Types.Schemas)
                {
                    foreach (System.Xml.Schema.XmlSchemaObject externalSchema in wsdlSchema.Includes)
                    {
                        if (externalSchema is System.Xml.Schema.XmlSchemaImport)
                        {
                            Uri baseUri = new Uri(wsdlURI);
                            Uri schemaUri = new Uri(baseUri, ((System.Xml.Schema.XmlSchemaExternal)externalSchema).SchemaLocation);
                            wsdlStream = client.OpenRead(schemaUri);
                            System.Xml.Schema.XmlSchema schema = System.Xml.Schema.XmlSchema.Read(wsdlStream, null);
                            wsdlImport.Schemas.Add(schema);
                        }
                    }
                }

     

    Tuesday, June 5, 2007 4:47 PM
  • User634351653 posted

    Ok... so, that's the manual way of doing it!

    I wonder why  the ServiceDescriptor does not offer an event that allow one to resolve the import references (wouldn't it be nice?!?!)... but ok!


    Thanks for your input [:)]

    jmn 

    Wednesday, June 6, 2007 2:45 AM
  • User-309816304 posted

    HI JohnBundred,

    for suppose

    i have in main wsdl

    <wsdl:types>
    <xsd:schema targetNamespace="http://tempuri.org/Imports">
    <xsd:import schemaLocation="http://localhost:8787/service/test?xsd=xsd0" namespace="http://tempuri.org/"/>
    <xsd:import schemaLocation="http://localhost:8787/service/test?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
    <xsd:import schemaLocation="http://localhost:8787/service/test?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/TestService"/>
    <xsd:import schemaLocation="http://localhost:8787/service/test?xsd=xsd3" namespace="http://othernamespace.org/"/>
    </xsd:schema>
    </wsdl:types>
    and in one of the schema location say "http://localhost:8787/service/test?xsd=xsd0"
    i have schema as
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
    <xs:import schemaLocation="http://localhost:8787/service/test?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/TestService"/>
    <xs:import schemaLocation="http://localhost:8787/service/test?xsd=xsd3" namespace="http://othernamespace.org/"/>
    like wise i have recursivel import tags
    so i used recursion to solve this but i am receiveing an exception (as error in wsdl).but my wsdl works fine in SoapUI.
    code i used for recursive traversal is given below.

    private void parseSchema(Uri e)
    {

              System.IO.Stream wsdlStream = null;
              WebClient client = null;
              client = new WebClient();
              wsdlStream = client.OpenRead(e);

              ServiceDescription wsdl = ServiceDescription.Read(wsdlStream);
               ServiceDescriptionImporter wsdlImport = new ServiceDescriptionImporter();
               wsdlImport.AddServiceDescription(wsdl, null, null);

                foreach (XmlSchema s in wsdl.Types.Schemas)
                {
                          TargetSchemaSet.Add(s);
                           putElementsIntoSchema(s);
                           foreach (System.Xml.Schema.XmlSchemaObject externalSchema in s.Includes)
                           {
                                 if (externalSchema is System.Xml.Schema.XmlSchemaImport)
                                      {
                                           Uri baseUri = new Uri(tempSourceUri.ToString());
                                           Uri schemaUri = new Uri(baseUri, ((System.Xml.Schema.XmlSchemaExternal)externalSchema).SchemaLocation);
                                            parseSchema(schemaUri);

                                     }

                          }
    }

    }

    Thursday, September 11, 2014 6:58 AM
  • User-309816304 posted

    HI JohnBundred,

    for suppose

    i have in main wsdl

    <xml:schema targetNamespace="http://tempuri.org/Imports">

    <xsd:import schemaLocation="http://localhost:8787/service/test?xsd=xsd0" namespace="http://tempuri.org/"/>=

    <xsd:import schemaLocation="http://localhost:8787/service/test?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>

    </xsd:schema>

    </wsdl:types>

    and in one of the schema location say "http://localhost:8787/service/test?xsd=xsd0i have schema as

    <xs:import schemaLocation="http://localhost:8787/service/test?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/TestService"/><xs:import schemaLocation="http://localhost:8787/service/test?xsd=xsd3" namespace="http://othernamespace.org/"/>

    like wise i have recursivel import tags so i used recursion to solve this but i am receiveing an exception (as error in wsdl).but my wsdl works fine in SoapUI.code i used for recursive traversal is given below.

    private void parseSchema(Uri e)
    {

              System.IO.Stream wsdlStream = null;
              WebClient client = null;
              client = new WebClient();
              wsdlStream = client.OpenRead(e);

              ServiceDescription wsdl = ServiceDescription.Read(wsdlStream);
               ServiceDescriptionImporter wsdlImport = new ServiceDescriptionImporter();
               wsdlImport.AddServiceDescription(wsdl, null, null);

                foreach (XmlSchema s in wsdl.Types.Schemas)
                {
                          TargetSchemaSet.Add(s);
                           putElementsIntoSchema(s);
                           foreach (System.Xml.Schema.XmlSchemaObject externalSchema in s.Includes)
                           {
                                 if (externalSchema is System.Xml.Schema.XmlSchemaImport)
                                      {
                                           Uri baseUri = new Uri(tempSourceUri.ToString());
                                           Uri schemaUri = new Uri(baseUri, ((System.Xml.Schema.XmlSchemaExternal)externalSchema).SchemaLocation);
                                            parseSchema(schemaUri);

                                     }

                          }
    }

    }

    </div> </div> </div> </div>

    Thursday, September 11, 2014 6:59 AM