Consume and Invoke SOAP WebServices at Runtime - Dynamic Web Service client from WSDL file

后端 未结 1 1966
春和景丽
春和景丽 2020-12-06 03:10

Requirement:

  1. Customer to give the SOAP Web-service\'s WSDL at runtime i.e pick the WSDL file from a file share location.
  2. Consume the
相关标签:
1条回答
  • 2020-12-06 03:36

    There is a solution for doing this described in this article:

    Generate proxy code for a web service dynamically

    Although you can open that link and read it, I include the code here, just in case that link dies anytime:

    This method returns the list of operations exposed by the web service. I have used ServiceDescription to achieve that as I was not able to reflect only the web method names from the generated assmebly. With the operation names available, all that remains is to find out the input and return parameters for each method.

    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;
    }
    

    This method returns the input parameters in ParameterInfo[] list. To get the output parameter, just replace the call to GetParamters() on MethodInfo class with ReturnParameter property and put that inside a new method. Put these 3 methods inside a dll and add a reference to it from any client application. That's all. Just provide the URL and consume the web service, any web service. You don't have to go through the procedure of creating a proxy file every time you want to consume a new web service.

    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 讨论(0)
提交回复
热议问题