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