2014-11-26 18 views
5

Requisito:Consumare e invocare servizi Web SOAP in fase di esecuzione - cliente dinamico Web Service dal file WSDL

  1. clienti per dare WSDL SOAP di Web-service in fase di esecuzione cioè scegliere il file WSDL da un percorso di condivisione di file.
  2. Consuma il WSDL e chiama il metodo scelto dal Cliente sull'interfaccia utente e gestisce la risposta.

Non riesco a utilizzare MetadataExchangeClient poiché il WSDL non sarà ospitato.

Implementazione:

var serviceDescription = ServiceDescription.Read(@"C:\Contacts.WSDL"); 
var metadataSection = new MetadataSection 
{ 
Dialect = MetadataSection.ServiceDescriptionDialect, 
Identifier = serviceDescription.TargetNamespace, 
Metadata = serviceDescription 
}; 

var metadataSections = new List<MetadataSection> {metadataSection}; 
var metadatSet = new MetadataSet(metadataSections); 
var wsdlImporter = new WsdlImporter(metadatSet); 
var services = wsdlImporter.ImportAllEndpoints(); 

Blocchi stradali:

  1. Il codice di cui sopra non ha potuto estrarre i endpoint del servizio a tutti. Quindi, ho dovuto creare manualmente un endpoint del servizio.
  2. non ho potuto elencare tutti i metodi contenuti nel WSDL sopra e suoi ingressi associati/uscite nella fase (da utilizzare nella operationName variabile e operationParameters sotto)
object retVal = instance.GetType().GetMethod(operationName) 
         .Invoke(instance, operationParameters); // Invoke 

Ho provato codificando a fondo il nome dell'operazione, analizzato manualmente dal WSDL, ma poi non è riuscito con i parametri. E 'in attesa di un tipo complesso che contiene la gerarchia, come di seguito:

ContactInput -> ListOfContacts -> Contatti -> nome, cognome

Passi successivi:

se qualcuno potesse aiutami a sistemare i posti di blocco, poi posso procedere con l'approccio di cui sopra.

Else, devo avviare la ricerca sull'uso della svcutil.exe in fase di esecuzione

Grazie, Dev

risposta

4

C'è una soluzione per fare questo descritto in questo articolo:

Generate proxy code for a web service dynamically

Sebbene sia possibile aprire quel collegamento e leggerlo, includo il codice qui, nel caso in cui il collegamento muoia in qualsiasi momento:

Questo metodo restituisce l'elenco delle operazioni esposte dal servizio Web. Ho usato ServiceDescription per raggiungere questo dato che non ero in grado di riflettere solo i nomi dei metodi web generati in modo definitivo. Con i nomi delle operazioni disponibili, non resta che scoprire i parametri di input e di ritorno per ciascun metodo.

public string[] GenerateProxyAssembly() 
{ 
    //create a WebRequest object and fetch the WSDL file for the web service 
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(this.uri); 
    request.Credentials = CredentialCache.DefaultCredentials; 
    HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
    System.IO.Stream stream = response.GetResponseStream(); 

    //read the downloaded WSDL file 
    ServiceDescription desc = ServiceDescription.Read(stream); 

    //find out the number of operations exposed by the web service 
    //store the name of the operations inside the string array 
    //iterating only through the first binding exposed as 
    //the rest of the bindings will have the same number 
    int i = 0; 
    Binding binding = desc.Bindings[0]; 
    OperationBindingCollection opColl = binding.Operations; 
    foreach (OperationBinding operation in opColl) 
    { 
    listOfOperations[i++] = operation.Name; 
    } 

    //initializing a ServiceDescriptionImporter object 
    ServiceDescriptionImporter importer = new ServiceDescriptionImporter(); 

    //set the protocol to SOAP 1.1 
    importer.ProtocolName = "Soap12"; 

    //setting the Style to Client in order to generate client proxy code 
    importer.Style = ServiceDescriptionImportStyle.Client; 

    //adding the ServiceDescription to the Importer object 
    importer.AddServiceDescription(desc, null, null); 
    importer.CodeGenerationOptions = CodeGenerationOptions.GenerateNewAsync; 

    //Initialize the CODE DOM tree in which we will import the 
    //ServiceDescriptionImporter 
    CodeNamespace nm = new CodeNamespace(); 
    CodeCompileUnit unit = new CodeCompileUnit(); 
    unit.Namespaces.Add(nm); 

    //generating the client proxy code 
    ServiceDescriptionImportWarnings warnings = importer.Import(nm, unit); 

    if (warnings == 0) 
    { 
    //set the CodeDOMProvider to C# to generate the code in C# 
    System.IO.StringWriter sw = new System.IO.StringWriter(); 
    CodeDomProvider provider = CodeDomProvider.CreateProvider("C#"); 
    provider.GenerateCodeFromCompileUnit(unit, sw, new CodeGeneratorOptions()); 

    //creating TempFileCollection 
    //the path of the temp folder is hardcoded 
    TempFileCollection coll = new TempFileCollection(@"C:\wmpub\tempFiles"); 
    coll.KeepFiles = false; 

    //setting the CompilerParameters for the temporary assembly 
    string[] refAssembly = { "System.dll", "System.Data.dll", 
     "System.Web.Services.dll", "System.Xml.dll" }; 
    CompilerParameters param = new CompilerParameters(refAssembly); 
    param.GenerateInMemory = true; 
    param.TreatWarningsAsErrors = false; 
    param.OutputAssembly = "WebServiceReflector.dll"; 
    param.TempFiles = coll; 

    //compile the generated code into an assembly 
    //CompilerResults results = provider.CompileAssemblyFromDom(param, unitArr); 
    CompilerResults results 
     = provider.CompileAssemblyFromSource(param, sw.ToString()); 
    this.assem = results.CompiledAssembly; 
    } 

    //return the list of operations exposed by the web service 
    return listOfOperations; 
} 

Questo metodo restituisce i parametri di input in ParameterInfo elenco []. Per ottenere il parametro di output, è sufficiente sostituire la chiamata a GetParamters() sulla classe MethodInfo con la proprietà ReturnParameter e inserirla all'interno di un nuovo metodo. Metti questi 3 metodi in una DLL e aggiungi un riferimento ad essa da qualsiasi applicazione client. È tutto. Basta fornire l'URL e consumare il servizio web, qualsiasi servizio web. Non è necessario seguire la procedura di creazione di un file proxy ogni volta che si desidera utilizzare un nuovo servizio Web.

public ParameterInfo[] ReturnInputParameters(string methodName) 
{ 
    //create an instance of the web service type 
    //////////////to do///////////////////////// 
    //get the name of the web service dynamically from the wsdl 
    Object o = this.assem.CreateInstance("Service"); 
    Type service = o.GetType(); 
    ParameterInfo[] paramArr = null; 

    //get the list of all public methods available in the generated //assembly 
    MethodInfo[] infoArr = service.GetMethods(); 

    foreach (MethodInfo info in infoArr) 
    { 
    //get the input parameter information for the 
    //required web method 
    if (methodName.Equals(info.Name)) 
    { 
     paramArr = info.GetParameters(); 
    } 
    } 

    return paramArr; 
} 
+0

Grazie per i puntatori. Lo proveremo e aggiorneremo se funziona per me. – Dev

Problemi correlati