[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