using System; using System.Net; using System.IO; using System.CodeDom; using System.CodeDom.Compiler; using System.Collections; using System.ComponentModel; using System.Web.Services; using System.Web.Services.Description; using System.Reflection; using Microsoft.CSharp; using System.Collections.Specialized; namespace WSDLLateBinding { /// /// Summary description for Class1. /// public class Client { public Client() {} public Object GetMethodStub(SoapRequest Request) { // prepare the WSDL service description in memory. ServiceDescriptionImporter sdImp = new ServiceDescriptionImporter(); // the enhanced version would allow a URL to a WSDL as a parameter // and download it to local disk. WSDLLateBinding.Utils Utils = new WSDLLateBinding.Utils(); ServiceDescription sDesc = ServiceDescription.Read(Utils.GetHttpStream(Request.wsdlfile, "myproxy", 80)); // could be dynamic for future versions: http get, http post, soap. sdImp.ProtocolName = "soap"; sdImp.AddServiceDescription(sDesc, null, Request.baseUrl); // The parameter to the following ctor should be a dynamically // generated Namespace string (e.g. get it from the XML Namespace). CodeNamespace cnSpace = new CodeNamespace(Request.dynamicNameSpace); CodeCompileUnit ccUnit = new CodeCompileUnit(); ServiceDescriptionImportWarnings sdiWarning = sdImp.Import(cnSpace, ccUnit); // Pass the CodeCompileUnit to a System.CodeDom.CodeProvider, // such as Microsoft.CSharp.CSharpCodeProvider, to do the compilation. // Then load the disk assembly with Assembly.Load and use reflection to find // the proxy class and method you want to call. CSharpCodeProvider cdp = new CSharpCodeProvider(); // this is for source code generation ICodeGenerator cg = cdp.CreateGenerator(); // this is for assembly generation ICodeCompiler cc = cdp.CreateCompiler(); String fileNameSource = Request.dynFileNameSource + ".cs"; String fileNameAss = Request.dynFileNameSource + ".dll"; // this is for source code StreamWriter sw = new StreamWriter(fileNameSource); // actually generate the WS proxy code. cg.GenerateCodeFromNamespace(cnSpace, sw, null); sw.Flush(); sw.Close(); // this is for assembly compilation. CompilerParameters cp = new CompilerParameters(new String[] { "System.dll", "System.Xml.dll", "System.Web.Services.dll", "System.Data.dll"} ); cp.GenerateExecutable = false; cp.GenerateInMemory = false; // has to be a dynamic value - for demonstration purposes only. cp.MainClass = Request.ServiceName; cp.OutputAssembly = fileNameAss; cp.IncludeDebugInformation = true; // this doesn't work. Produces empty assembly because the XmlSerialzer // doesn't support dynamic modules. //CompilerResults cr = cc.CompileAssemblyFromDom(cp, ccUnit); CompilerResults cr = cc.CompileAssemblyFromFile(cp, fileNameSource); // load generated assembly from disk and use reflection to find and invoke the methods Assembly ass = Assembly.Load(Request.dynFileNameSource); // Should be dynamic in generic solution. Type tDyn = ass.GetType(Request.dynamicNameSpace + "." + Request.ServiceName); // Create an instance of the class. Object obj = Activator.CreateInstance(tDyn); return obj; } public Object ExecuteMethod(SoapRequest Request) { // prepare the WSDL service description in memory. ServiceDescriptionImporter sdImp = new ServiceDescriptionImporter(); // the enhanced version would allow a URL to a WSDL as a parameter // and download it to local disk. WSDLLateBinding.Utils Utils = new WSDLLateBinding.Utils(); ServiceDescription sDesc = ServiceDescription.Read(Utils.GetHttpStream(Request.wsdlfile, "myproxy", 80)); // could be dynamic for future versions: http get, http post, soap. sdImp.ProtocolName = "soap"; sdImp.AddServiceDescription(sDesc, null, Request.baseUrl); // The parameter to the following ctor should be a dynamically // generated Namespace string (e.g. get it from the XML Namespace). CodeNamespace cnSpace = new CodeNamespace(Request.dynamicNameSpace); CodeCompileUnit ccUnit = new CodeCompileUnit(); ServiceDescriptionImportWarnings sdiWarning = sdImp.Import(cnSpace, ccUnit); // Pass the CodeCompileUnit to a System.CodeDom.CodeProvider, // such as Microsoft.CSharp.CSharpCodeProvider, to do the compilation. // Then load the disk assembly with Assembly.Load and use reflection to find // the proxy class and method you want to call. CSharpCodeProvider cdp = new CSharpCodeProvider(); // this is for source code generation ICodeGenerator cg = cdp.CreateGenerator(); // this is for assembly generation ICodeCompiler cc = cdp.CreateCompiler(); String fileNameSource = Request.dynFileNameSource + ".cs"; String fileNameAss = Request.dynFileNameSource + ".dll"; // this is for source code StreamWriter sw = new StreamWriter(fileNameSource); // actually generate the WS proxy code. cg.GenerateCodeFromNamespace(cnSpace, sw, null); sw.Flush(); sw.Close(); // this is for assembly compilation. CompilerParameters cp = new CompilerParameters(new String[] { "System.dll", "System.Xml.dll", "System.Web.Services.dll", "System.Data.dll"} ); cp.GenerateExecutable = false; cp.GenerateInMemory = false; // has to be a dynamic value - for demonstration purposes only. cp.MainClass = Request.ServiceName; cp.OutputAssembly = fileNameAss; cp.IncludeDebugInformation = true; // this doesn't work. Produces empty assembly because the XmlSerialzer // doesn't support dynamic modules. //CompilerResults cr = cc.CompileAssemblyFromDom(cp, ccUnit); CompilerResults cr = cc.CompileAssemblyFromFile(cp, fileNameSource); // load generated assembly from disk and use reflection to find and invoke the methods Assembly ass = Assembly.Load(Request.dynFileNameSource); // Should be dynamic in generic solution. Type tDyn = ass.GetType(Request.dynamicNameSpace + "." + Request.ServiceName); // Create an instance of the class. Object obj = Activator.CreateInstance(tDyn); // Create the args array - should be dynamic in generic solution. //int paramCount =0; int paramCount=Request.count(); Object[] args= new Object[paramCount]; // Set the arguments - should be dynamic in generic solution. for(int x=0;x