From: http://rainsts.net/article.asp? Id = 304
Most of the time, we use "add web reference..." to create a client proxy class to call WebService. However, in some cases, we may need to dynamically call an unknown service while the program is running. In the. NET Framework system. Web. Services. Description namespace, we need something.
Procedure:
1. Download the WSDL data from the target URL.
2. Use servicedescription to create and format the WSDL document file.
3. Use servicedescriptionimporter to create the client proxy class.
4. Use codedom to dynamically create client proxy assembly.
5. Call related WebService Methods Using Reflection.
OK. Let's take a look at the specific example.
The target WebService to be called. Its URL is http: // localhost: 60436/learn. Web/WebService. asmx.
Helloworld. asmx
[WebService (namespace = "http://www.rainsts.net/", description = "my web services")]
[Webservicebinding (conformsto = wsiprofiles. basicprofile1_1)]
Public class WebService: system. Web. Services. WebService {
Public WebService (){
}
[Webmethod]
Public String helloworld ()
{
Return "Hello wolrd! ";
}
}
1. Dynamic WebService call
Client dynamic call code
Using system. IO;
Using system. net;
Using system. reflection;
Using system. codedom;
Using system. codedom. compiler;
Using system. Web. Services;
Using system. Web. Services. description;
Using system. Web. Services. Protocols;
Using system. xml. serialization;
// 1. Use WebClient to download the WSDL information.
WebClient web = new WebClient ();
Stream stream = web. openread ("http: // localhost: 60436/learn. Web/WebService. asmx? WSDL ");
// 2. Create and format the WSDL document.
Servicedescription description = servicedescription. Read (Stream );
// 3. Create a client proxy class.
Servicedescriptionimporter importer = new servicedescriptionimporter ();
Importer. protocolname = "Soap"; // specify the access protocol.
Importer. Style = servicedescriptionimportstyle. Client; // generate a client proxy.
Importer. codegenerationoptions = codegenerationoptions. generateproperties | codegenerationoptions. generatenewasync;
Importer. addservicedescription (description, null, null); // Add a WSDL document.
// 4. Use codedom to compile the client proxy class.
Codenamespace nmspace = new codenamespace (); // Add a namespace for the proxy class. The default value is global space.
Codecompileunit unit = new codecompileunit ();
Unit. namespaces. Add (nmspace );
Servicedescriptionimportwarnings warning = importer. Import (nmspace, Unit );
Codedomprovider provider = codedomprovider. createprovider ("CSHARP ");
Compilerparameters parameter = new compilerparameters ();
Parameter. generateexecutable = false;
Parameter. generateinmemory = true;
Parameter. referencedassemblies. Add ("system. dll ");
Parameter. referencedassemblies. Add ("system. xml. dll ");
Parameter. referencedassemblies. Add ("system. Web. Services. dll ");
Parameter. referencedassemblies. Add ("system. Data. dll ");
Compilerresults result = provider. compileassemblyfromdom (parameter, Unit );
// 5. Use reflection to call WebService.
If (! Result. errors. haserrors)
{
Assembly ASM = result. compiledassembly;
Type T = ASM. GetType ("WebService"); // if you have added a namespace for the proxy class before, add the namespace to the front of the type.
Object o = activator. createinstance (t );
Methodinfo method = T. getmethod ("helloworld ");
Console. writeline (method. Invoke (O, null ));
}
2. Generate the client proxy Assembly File
The above code completes the dynamic calling process by creating a dynamic assembly in the memory. If you want to save the Assembly file generated by the client proxy class to the hard disk, you can make the following changes. After the Assembly file is generated, we can load it and call it through Assembly. loadfrom. Systems that require multiple calls are much more efficient than generating a dynamic assembly each time.
Using system. IO;
Using system. net;
Using system. codedom;
Using system. codedom. compiler;
Using system. Web. Services;
Using system. Web. Services. description;
Using system. Web. Services. Protocols;
Using system. xml. serialization;
// 1. Use WebClient to download the WSDL information.
WebClient web = new WebClient ();
Stream stream = web. openread ("http: // localhost: 60436/learn. Web/WebService. asmx? WSDL ");
// 2. Create and format the WSDL document.
Servicedescription description = servicedescription. Read (Stream );
// 3. Create a client proxy class.
Servicedescriptionimporter importer = new servicedescriptionimporter ();
Importer. protocolname = "Soap"; // specify the access protocol.
Importer. Style = servicedescriptionimportstyle. Client; // generate a client proxy.
Importer. codegenerationoptions = codegenerationoptions. generateproperties | codegenerationoptions. generatenewasync;
Importer. addservicedescription (description, null, null); // Add a WSDL document.
// 4. Use codedom to compile the client proxy class.
Codenamespace nmspace = new codenamespace (); // Add a namespace for the proxy class. The default value is global space.
Codecompileunit unit = new codecompileunit ();
Unit. namespaces. Add (nmspace );
Servicedescriptionimportwarnings warning = importer. Import (nmspace, Unit );
Codedomprovider provider = codedomprovider. createprovider ("CSHARP ");
Compilerparameters parameter = new compilerparameters ();
Parameter. generateexecutable = false;
Parameter. outputassembly = "test. dll"; // you can specify any file name you need.
Parameter. referencedassemblies. Add ("system. dll ");
Parameter. referencedassemblies. Add ("system. xml. dll ");
Parameter. referencedassemblies. Add ("system. Web. Services. dll ");
Parameter. referencedassemblies. Add ("system. Data. dll ");
Compilerresults result = provider. compileassemblyfromdom (parameter, Unit );
If (result. errors. haserrors)
{
// Display the compilation error message
}
Demo of calling Assembly File
Assembly asm = Assembly.LoadFrom("test.dll");
Type t = asm.GetType("WebService");
object o = Activator.CreateInstance(t);
MethodInfo method = t.GetMethod("HelloWorld");
Console.WriteLine(method.Invoke(o, null));
3. Obtain the client proxy source code
Another scenario is that we need to obtain the C # source code of the client proxy class.
Using system. IO;
Using system. net;
Using system. codedom;
Using system. codedom. compiler;
Using system. Web. Services;
Using system. Web. Services. description;
Using system. Web. Services. Protocols;
Using system. xml. serialization;
// 1. Use WebClient to download the WSDL information.
WebClient web = new WebClient ();
Stream stream = web. openread ("http: // localhost: 60436/learn. Web/WebService. asmx? WSDL ");
// 2. Create and format the WSDL document.
Servicedescription description = servicedescription. Read (Stream );
// 3. Create a client proxy class.
Servicedescriptionimporter importer = new servicedescriptionimporter ();
Importer. protocolname = "Soap"; // specify the access protocol.
Importer. Style = servicedescriptionimportstyle. Client; // generate a client proxy.
Importer. codegenerationoptions = codegenerationoptions. generateproperties | codegenerationoptions. generatenewasync;
Importer. addservicedescription (description, null, null); // Add a WSDL document.
// 4. Use codedom to compile the client proxy class.
Codenamespace nmspace = new codenamespace (); // Add a namespace for the proxy class. The default value is global space.
Codecompileunit unit = new codecompileunit ();
Unit. namespaces. Add (nmspace );
Servicedescriptionimportwarnings warning = importer. Import (nmspace, Unit );
Codedomprovider provider = codedomprovider. createprovider ("CSHARP ");
// 5. Save the source code to the file. Of course, you can also directly save it to the memory string.
Textwriter writer = file. createtext ("test. cs"); // specify the source code file name.
Provider. generatecodefromcompileunit (unit, writer, null );
Writer. Flush ();
Writer. Close ();