[Mono-list] Referencing a webservice

Loren Bandiera lorenb at mmgsecurity.com
Fri Feb 24 10:34:13 EST 2006


I needed to do this myself recently for one of my projects. I wanted to
be able to use a SOAP-based web service dynamically.

I looked around the net trying to figure out how to go about doing that.
Fortunately other people had attempted this before and I found the bit
and pieces I needed. 

The basic steps involved are:

- Download the WSDL file
- Discover the service description
- Generate code for the service
- Compile the code and create a new assembly
- Call methods on the new assembly

Here is some sample code:

using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Configuration;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
using System.Web.Services.Description;
using System.Web.Services.Discovery;
using System.Xml.Schema;
using Microsoft.CSharp;


AssemblyGenerator generator = new AssemblyGenerator ();
ArrayList descriptions = new ArrayList ();
ArrayList schemas = new ArrayList ();

DiscoveryClientProtocol dcc = new DiscoveryClientProtocol ();
dcc.AllowAutoRedirect = true;
dcc.DiscoverAny ("http://foo.com/bar.wsdl");
dcc.ResolveAll ();

foreach (object doc in dcc.Documents.Values) {

  if (doc is ServiceDescription)
     descriptions.Add ((ServiceDescription)doc);
  else if (doc is XmlSchema)
     schemas.Add ((XmlSchema)doc);
}

if (descriptions.Count == 0)
  throw new Exception ("Error getting WSDL file");

CodeNamespace codeNamespace = new CodeNamespace ("Foo.Bar");
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap";

foreach (ServiceDescription sd in descriptions)
   importer.AddServiceDescription(sd, null, null);

foreach (XmlSchema sc in schemas)
   importer.Schemas.Add (sc);

importer.Import(codeNamespace, null);

CodeDomProvider provider = new CSharpCodeProvider();
ICodeGenerator generator = provider.CreateGenerator();

StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter (sb);
				
generator.GenerateCodeFromNamespace (codeNamespace, sw, null);
string src = sb.ToString();
sw.Close();
			
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.Xml.dll");
cp.ReferencedAssemblies.Add("System.Web.Services.dll");
cp.ReferencedAssemblies.Add(System.Reflection.Assembly.GetExecutingAssembly().Location);

ICodeCompiler compiler = provider.CreateCompiler();
CompilerResults cr = compiler.CompileAssemblyFromSource (cp, src);

if (cr.Errors.Count > 0) {
   foreach (CompilerError ce in cr.Errors)
      Console.WriteLine(ce.ToString());
                    
    throw new Exception("Build failed");
}

Assembly newAssembly = cr.CompiledAssembly;
newAssembly.SomeMethod ();


On Fri, 2006-02-24 at 09:35 -0500, Shawn Vose wrote:
> Can anyone tell me how to create a reference a web service at run time 
> instead of during compile time. I am thinking it would be a late bound 
> object but dont know how to go about doing it. If someone has the answer 
> or a reference to some docs that would be great.
> 

-- 
Loren Bandiera <lorenb at mmgsecurity.com>
MMG Security, Inc.



More information about the Mono-list mailing list