2010-12-15 17 views
5

Estoy intentando analizar WSDL, siguiendo el ejemplo dado here.Parse Complex WSDL Parameter Information

El autor señala, en los comentarios, que el ejemplo no es capaz de profundizar en tipos de datos complejos.

Y, de hecho, cuando ejecuto el ejemplo, parece que ni siquiera maneja tipos de datos simples.

He buscado en la clase System.Web.Services.Description.ServiceDescription, que se utiliza en el ejemplo, pero no puedo encontrar ningún parámetro real o información de tipo de devolución en tiempo de ejecución. Supongo que puedo necesitar hacer un análisis manual de un archivo xsd.

Parece que google y stackoverflow carecen de un ejemplo completo de cómo profundizar en tipos complejos mediante programación, así que ... ¿cómo debo hacer esto?

Respuesta

16

Esto no es bastante - pero hace el trabajo (con suerte;). Basé este código en parte en el enlace que proporcionó, y luego agregué alguna recursión para analizar los diferentes tipos incluidos en el esquema, así como los elementos internos y sus tipos de datos. Esto definitivamente no tiene en cuenta todas las posibilidades en un esquema XML, pero creo que ejemplifica lo suficiente como para agregar complejidad a esto si es necesario.

Espero que esto ayude !!!!

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     //Build the URL request string 
     UriBuilder uriBuilder = new UriBuilder(@"http://digicomdev:8888/digitalOrderBroker/digitalOrderBroker.asmx"); 
     uriBuilder.Query = "WSDL"; 

     HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(uriBuilder.Uri); 
     webRequest.ContentType = "text/xml;charset=\"utf-8\""; 
     webRequest.Method = "GET"; 
     webRequest.Accept = "text/xml"; 

     //Submit a web request to get the web service's WSDL 
     ServiceDescription serviceDescription; 
     using (WebResponse response = webRequest.GetResponse()) 
     { 
      using (Stream stream = response.GetResponseStream()) 
      { 
       serviceDescription = ServiceDescription.Read(stream); 
      } 
     } 

     //Loop through the port types in the service description and list all of the 
     //web service's operations and each operations input/output 
     foreach (PortType portType in serviceDescription.PortTypes) 
     { 
      foreach (Operation operation in portType.Operations) 
      { 
       Console.Out.WriteLine(operation.Name); 

       foreach (var message in operation.Messages) 
       { 
        if (message is OperationInput) 
         Console.Out.WriteLine("Input Message: {0}", ((OperationInput) message).Message.Name); 
        if (message is OperationOutput) 
         Console.Out.WriteLine("Output Message: {0}", ((OperationOutput) message).Message.Name); 

        foreach (Message messagePart in serviceDescription.Messages) 
        { 
         if (messagePart.Name != ((OperationMessage) message).Message.Name) continue; 

         foreach (MessagePart part in messagePart.Parts) 
         { 
          Console.Out.WriteLine(part.Name); 
         } 
        } 
       } 
       Console.Out.WriteLine(); 
      } 
     } //End listing of types 

     //Drill down into the WSDL's complex types to list out the individual schema elements 
     //and their data types 
     Types types = serviceDescription.Types; 
     XmlSchema xmlSchema = types.Schemas[0]; 

     foreach (object item in xmlSchema.Items) 
     { 
      XmlSchemaElement schemaElement = item as XmlSchemaElement; 
      XmlSchemaComplexType complexType = item as XmlSchemaComplexType; 

      if (schemaElement != null) 
      { 
       Console.Out.WriteLine("Schema Element: {0}", schemaElement.Name); 

       XmlSchemaType schemaType = schemaElement.SchemaType; 
       XmlSchemaComplexType schemaComplexType = schemaType as XmlSchemaComplexType; 

       if (schemaComplexType != null) 
       { 
        XmlSchemaParticle particle = schemaComplexType.Particle; 
        XmlSchemaSequence sequence = 
         particle as XmlSchemaSequence; 
        if (sequence != null) 
        { 
         foreach (XmlSchemaElement childElement in sequence.Items) 
         { 
          Console.Out.WriteLine(" Element/Type: {0}:{1}", childElement.Name, 
                childElement.SchemaTypeName.Name); 
         } 
        } 
       } 
      } 
      else if (complexType != null) 
      { 
       Console.Out.WriteLine("Complex Type: {0}", complexType.Name); 
       OutputElements(complexType.Particle); 
      } 
      Console.Out.WriteLine(); 
     } 

     Console.Out.WriteLine(); 
     Console.In.ReadLine(); 
    } 

    private static void OutputElements(XmlSchemaParticle particle) 
    { 
     XmlSchemaSequence sequence = particle as XmlSchemaSequence; 
     XmlSchemaChoice choice = particle as XmlSchemaChoice; 
     XmlSchemaAll all = particle as XmlSchemaAll; 

     if (sequence != null) 
     { 
      Console.Out.WriteLine(" Sequence"); 

      for (int i = 0; i < sequence.Items.Count; i++) 
      { 
       XmlSchemaElement childElement = sequence.Items[i] as XmlSchemaElement; 
       XmlSchemaSequence innerSequence = sequence.Items[i] as XmlSchemaSequence; 
       XmlSchemaChoice innerChoice = sequence.Items[i] as XmlSchemaChoice; 
       XmlSchemaAll innerAll = sequence.Items[i] as XmlSchemaAll; 

       if (childElement != null) 
       { 
        Console.Out.WriteLine(" Element/Type: {0}:{1}", childElement.Name, 
              childElement.SchemaTypeName.Name);       
       } 
       else OutputElements(sequence.Items[i] as XmlSchemaParticle); 
      } 
     } 
     else if (choice != null) 
     { 
      Console.Out.WriteLine(" Choice"); 
      for (int i = 0; i < choice.Items.Count; i++) 
      { 
       XmlSchemaElement childElement = choice.Items[i] as XmlSchemaElement; 
       XmlSchemaSequence innerSequence = choice.Items[i] as XmlSchemaSequence; 
       XmlSchemaChoice innerChoice = choice.Items[i] as XmlSchemaChoice; 
       XmlSchemaAll innerAll = choice.Items[i] as XmlSchemaAll; 

       if (childElement != null) 
       { 
        Console.Out.WriteLine(" Element/Type: {0}:{1}", childElement.Name, 
              childElement.SchemaTypeName.Name); 
       } 
       else OutputElements(choice.Items[i] as XmlSchemaParticle); 
      } 

      Console.Out.WriteLine(); 
     } 
     else if (all != null) 
     { 
      Console.Out.WriteLine(" All"); 
      for (int i = 0; i < all.Items.Count; i++) 
      { 
       XmlSchemaElement childElement = all.Items[i] as XmlSchemaElement; 
       XmlSchemaSequence innerSequence = all.Items[i] as XmlSchemaSequence; 
       XmlSchemaChoice innerChoice = all.Items[i] as XmlSchemaChoice; 
       XmlSchemaAll innerAll = all.Items[i] as XmlSchemaAll; 

       if (childElement != null) 
       { 
        Console.Out.WriteLine(" Element/Type: {0}:{1}", childElement.Name, 
              childElement.SchemaTypeName.Name); 
       } 
       else OutputElements(all.Items[i] as XmlSchemaParticle); 
      } 
      Console.Out.WriteLine(); 
     } 
    } 
} 
+1

martin, probé tu código pero XmlSchema xmlSchema = types.Schemas [0]; siempre es nulo –

+0

@ user465876: Mi mejor suposición es que su URL no apunta al WSDL correctamente. ¡Espero que ayude! – pmartin

+0

¿Cómo puedo verificar eso? Abro la url del servicio con "? Wsdl" y se abre bien. Además, con el ejemplo original que se publicó, mi wsdl fue analizado y obtuve todos los tipos de datos simples. ¿Algo más que me pueda estar perdiendo? –

1

¿Qué desea hacer con el resultado analizado? Por ejemplo, puede usar ServiceDescription.Read y el importador para compilar un ensamblaje si desea obtener los tipos en memoria para usarlos.

Se puede ver un ejemplo de este tipo de enfoque en este script de PowerShell:

http://www.leeholmes.com/blog/2007/02/28/calling-a-webservice-from-powershell/

+0

Prefiero hacer algo un poco más ligero que compilar un conjunto. No necesariamente quiero hacer nada con el resultado, solo necesito una lista de los parámetros y los tipos de devolución (hasta el nivel atómico). – jaws