Use reflection to retrieve SOAP Web service methods

Written by stevey on February 28th, 2012

For a local object, retrieving its public methods is quite straightforward using Reflection. Sample codes below will suffice:

using System.Reflection;
using ....;
MethodInfo[] methods = typeof(LocalObjectType).GetMethods(BindingFlags.Public | BindingFlags.Static);
//sort by method names
Array.Sort(methods, delegate(MethodInfo m1, MethodInfo m2)
{ return m1.Name.CompareTo(m2.Name); });
foreach (MethodInfo mi in methods)
{ Console.WriteLine(mi.Name); }

But this does not work if my type is a proxy type to a remote web service. After some readings here and there, I finally was able to get a list of web service SOAP methods from a SOAP ASMX url. Here are the function I created to return a List of the MethodInfo:

using System; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Net;
using System.IO;
using System.Web.Services;
using System.Web.Services.Description;
using System.CodeDom;
using System.CodeDom.Compiler;


public List<MethodInfo> GetSoapMethods()
{
System.Net.WebClient client = new System.Net.WebClient(); string asmxUrl = "http://myservices.mydomain.com/Service.asmx";
if (!asmxUrl.Contains("?wsdl"))
asmxUrl += "?wsdl";
System.IO.Stream stream = client.OpenRead(asmxUrl);
//read service description
ServiceDescription desc = ServiceDescription.Read(stream);
//initialize a service description importer
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap12";
importer.AddServiceDescription(desc, null, null);
//generate a proxy client
importer.Style = ServiceDescriptionImportStyle.Client;
importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
CodeNamespace nmspace = new CodeNamespace();
CodeCompileUnit unit1 = new CodeCompileUnit();
unit1.Namespaces.Add(nmspace);
//import the service into the code-dom tree, this creates proxy codes that use the service
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit1);
if (warning == 0)
{
//System.Xml.Serialization.XmlSchemas mySchema = importer.Schemas;
//Console.WriteLine(mySchema.ToString());
//generate the proxy code
CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp");
//compile the assembly proxy with the appropriate references
string[] assemblyReferences = new string[5]{"System.dll","System.Web.Services.dll",
"System.Web.dll","System.Xml.dll","System.Data.dll"};
CompilerParameters parms = new CompilerParameters(assemblyReferences);
CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
Type[] types = results.CompiledAssembly.GetTypes();
Type foundType = null;
foreach (Type t in types)
{
if (t.BaseType == typeof(System.Web.Services.Protocols.SoapHttpClientProtocol))
{
Console.WriteLine(t.ToString());
foundType = t;
break;
}
}
//instantiate proxy class
object service = results.CompiledAssembly.CreateInstance(foundType.ToString());
//this will get all the methods, public or not in the webservice
List<MethodInfo> lstMethods = service.GetType().GetMethods().ToList();
return lstMethods;
}
else
{
Console.WriteLine("Warning..");
return null;
}
}

 

Leave a Comment