Saturday, October 4, 2008

Dynamic method invocation in .NET 2.0 using a WSDL

Recently I have come across a problem with generating proxy class on-the-fly by inputing a
WSDL file:
After a little bit of googling I came to partial success!!!
Below is the code for same:
Has anybody having a well furnished code? / comments , how to improve it??
How to generate proxy class without using Add Web Reference in VS ?
string wsdlurlstring = "http://localhost/InvokeWSTest/Service.asmx?wsdl";
#region WSDL INVOKE

private void WSDLInvoke()
{
string methodname = string.Empty;
Uri uri = new Uri(wsdlurlstring);
WebRequest webRequest = WebRequest.Create(uri);
NetworkCredential nc = new NetworkCredential("soapuseraccount", "soappasswd","MyDomain");
//webRequest.Credentials = nc;
System.IO.Stream requestStream = webRequest.GetResponse().GetResponseStream();
// Get a WSDL
ServiceDescription sd = ServiceDescription.Read(requestStream);
string sdName = sd.Services[0].Name;
// Initialize a service description
ServiceDescriptionImporter servImport = new ServiceDescriptionImporter();
servImport.AddServiceDescription(sd, String.Empty, String.Empty);
servImport.ProtocolName = "Soap";
servImport.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties;
CodeNamespace nameSpace = new CodeNamespace();
CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
codeCompileUnit.Namespaces.Add(nameSpace);// Set Warnings
ServiceDescriptionImportWarnings warnings = servImport.Import(nameSpace, codeCompileUnit);
if (warnings == 0)
{
StringWriter stringWriter = new StringWriter(System.Globalization.CultureInfo.CurrentCulture);
Microsoft.CSharp.CSharpCodeProvider prov = new Microsoft.CSharp.CSharpCodeProvider();
prov.GenerateCodeFromNamespace(nameSpace, stringWriter, new CodeGeneratorOptions());
string[] assemblyReferences = new string[2] { "System.Web.Services.dll", "System.Xml.dll" };
CompilerParameters param = new CompilerParameters(assemblyReferences);
param.GenerateExecutable = false;
param.GenerateInMemory = true;
param.TreatWarningsAsErrors = false;
param.WarningLevel = 4;
CompilerResults results = new CompilerResults(new TempFileCollection());
results = prov.CompileAssemblyFromDom(param, codeCompileUnit);
Assembly assembly = results.CompiledAssembly;
Type service = assembly.GetType(sdName);
Type[] serviceclasses = assembly.GetTypes();
PropertyInfo[] propInfoArray = service.GetProperties();
List webclasses = new List();
foreach (Type mytype in serviceclasses)
{
webclasses.Add(mytype.Name);
}
Activator.CreateInstance(serviceclasses[0]);
List listproperties = new List();
//if you want to access the properties inside the wsdl file ise propertyinfo class

foreach (PropertyInfo pinfo in propInfoArray)
{
if (pinfo.Name == "Credentials") listproperties.Add(pinfo.Name); break;
}
Object objC = Activator.CreateInstance(serviceclasses[0]);
Object obj2= Activator.CreateInstance(serviceclasses[1]);
Object [] objRow = Activator.CreateInstance(serviceclasses[1]);
Object objResponse = Activator.CreateInstance(serviceclasses[2]);
//object [] param1 = new object[];
methodInfo = service.GetMethods();
List webmethods = new List();
foreach (MethodInfo t in methodInfo)
{ if (t.Name == "Discover")break;webmethods.Add(t.Name); }
string meth2 = webmethods[32]; MethodName = webmethods[33];
//serviceclasses[1].GetType();
//object[] param1 = new object[param.Length];
foreach (MethodInfo mi in methodInfo)
{ foreach (string sss in webmethods) { if (mi.Name == MethodName) { try {
//Invoke Method
//Object obj = Activator.CreateInstance(service);
//create an array of object references
Object[] objCRow = new Object[1];
//Object[] objCRow = { objContinentRow };
Object response = mi.Invoke(objC, new object[] { objCRow });
break;
}
catch (TargetInvocationException expf) {throw expf.InnerException; }}}}}}}
#endregion WSDL INVOKE

No comments: