Three ways to dynamically invoke WebService __web

Source: Internet
Author: User
Tags abstract soap reflection require serialization web services wsdl

Three ways to dynamically invoke WebService

Most of the time we pass "add Web reference ..." The way the client proxy class is created calls WebService, but in some cases we may need to invoke an unknown service dynamically while the program is running. There is something we need in the System.Web.Services.Description namespace of the. NET Framework.

Specific steps:

1. Download the WSDL data from the destination URL.
2. Create and format a WSDL document file using ServiceDescription.
3. Create a client proxy class using ServiceDescriptionImporter.
4. Dynamically create client proxy class assemblies using CodeDom.
5. Call the relevant WebService method with reflection.

The above steps require a reference to the following four namespaces:

Using System.Web.Services.Description; Description of WS

The following few are used to dynamically generate code from the description and to dynamically compile the Get assembly

Using System.CodeDom;

Using Microsoft.csharp;

Using System.CodeDom.Compiler;

Several of the above namespaces include the following important classes:

Using the System.Web.Services.Description:

ServiceDescription//WS Description

ServiceDescriptionImporter//Generate client proxy classes by description, paying particular attention to the style

The following is a description of MSDN:

Xmlweb services interfaces are typically described by Web service Description Language (WSDL) files. For example, to get a WSDL description of a WEB service that uses ASP. Http://localhost/service.asmx exposed, just navigate to Http://localhost/service.asmx?WSDL. The ServiceDescriptionImporter class makes it easy to import the information contained in the WSDL description into the System.CodeDom.CodeCompileUnit object. By adjusting the value of the Style parameter, you can instruct the ServiceDescriptionImporter instance to generate a client proxy class (by transparently calling the class to provide the functionality of the Web service) or to generate an abstract class that encapsulates the functionality of the Web service without implementing the functionality. If you set the Style property to client, ServiceDescriptionImporter generates a proxy class for clients by calling these classes to provide a description of the functionality of the Web service. If you set the Style property to Server, the ServiceDescriptionImporter instance generates abstract classes that represent the functionality of the described XML Web services without implementation. You can then implement the classes that inherit from these abstract classes and implement the relevant methods.

Using the System.CodeDom:

codedomunit//It is used to set the namespace of dynamic code, class name, etc., can be written by the Servicedescriptionimporter.import () method of the WS description code to the class for dynamic compilation

Using the System.CodeDom.Compiler:

CodeDomProvider//for creating and retrieving instances of code generators and code compilers, we mainly use them to implement subclasses Csharecodeprovider

Can be generated directly with Csharecodeproviderprovider=new Csharecodeprovider (), or with Codedomprovider.createprovider ("CSharp") to generate

ICodeCompiler//is used to compile System.CodeDom-based source code representations.

It uses the CodeDomProvider CreateCompiler () method to

CompilerResults//Represents the compiled result returned from the compiler. It is compiled and returned by ICodeCompiler from the system.codedom tree contained in the specified CodeCompileUnit, based on the specified compiler settings. The Compiledassembly property indicates the compiled assembly.

Once you know the information above, you can call WS dynamically.


OK, take a look at the concrete examples.

We're going to call the target WebService, whose URL is Http://localhost:60436/Learn.WEB/WebService.asmx

HelloWorld.asmx

[WebService (Namespace = "http://www.rainsts.net/", description= "my Web Service")]
[WebServiceBinding (ConformsTo = wsiprofiles.basicprofile1_1)]
public class WebService:System.Web.Services.WebService {

Public WebService () {
}

[WebMethod]
public string HelloWorld ()
{
Return "Hello wolrd!";
}
}


1. Dynamic Call WebService

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 WSDL information.
WebClient Web = new WebClient ();
Stream Stream =web. OpenRead ("Http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");

2. Create and format a WSDL document.
ServiceDescription Description = Servicedescription.read (stream);

3. Create a client proxy proxy class.
ServiceDescriptionImporter importer = new ServiceDescriptionImporter ();

Importer. ProtocolName = "Soap"; Specifies the Access protocol.
Importer. Style = servicedescriptionimportstyle.client; Generates a client agent.
Importer. CodeGenerationOptions = Codegenerationoptions.generateproperties | Codegenerationoptions.generatenewasync;

Importer. Addservicedescription (description, NULL, NULL); Add a WSDL document.

4. Use the CodeDom to compile the client proxy class.
CodeNamespace nmspace = new CodeNamespace (); Adds a namespace to the proxy class, which defaults to 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. Call WebService using Reflection.
if (!result. Errors.haserrors)
{
Assembly asm = result.compiledassembly;
Type t = asm. GetType ("WebService"); If you have previously added a namespace to the proxy class, you need to add the namespace to the type before it.

Object o = activator.createinstance (t);
MethodInfo method = T.getmethod ("HelloWorld");
Console.WriteLine (method. Invoke (o, null));
}


2. Generating the client Agent assembly files

The above code completes the dynamic invocation process by creating dynamic assemblies in memory. If we want to save the client proxy class generation assembly file to the hard disk, you can make the following modifications. After generating the assembly file, we can load and make reflection calls through Assembly.LoadFrom (). For systems that require multiple calls, it is much more efficient than generating dynamic assemblies 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 WSDL information.
WebClient Web = new WebClient ();
Stream Stream =web. OpenRead ("Http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");

2. Create and format a WSDL document.
ServiceDescription Description = Servicedescription.read (stream);

3. Create a client proxy proxy class.
ServiceDescriptionImporter importer = new ServiceDescriptionImporter ();

Importer. ProtocolName = "Soap"; Specifies the Access protocol.
Importer. Style = servicedescriptionimportstyle.client; Generates a client agent.
Importer. CodeGenerationOptions = Codegenerationoptions.generateproperties | Codegenerationoptions.generatenewasync;

Importer. Addservicedescription (description, NULL, NULL); Add a WSDL document.

4. Use the CodeDom to compile the client proxy class.
CodeNamespace nmspace = new CodeNamespace (); Adds a namespace to the proxy class, which defaults to 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 that you want.
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 compilation error message
}


Invoke assembly file Demo

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. Get the client proxy class source code

Another scenario is that we need to get the C # source code for 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 WSDL information.
WebClient Web = new WebClient ();
Stream Stream =web. OpenRead ("Http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");

2. Create and format a WSDL document.
ServiceDescription Description = Servicedescription.read (stream);

3. Create a client proxy proxy class.
ServiceDescriptionImporter importer = new ServiceDescriptionImporter ();

Importer. ProtocolName = "Soap"; Specifies the Access protocol.
Importer. Style = servicedescriptionimportstyle.client; Generates a client agent.
Importer. CodeGenerationOptions = Codegenerationoptions.generateproperties | Codegenerationoptions.generatenewasync;

Importer. Addservicedescription (description, NULL, NULL); Add a WSDL document.

4. Use the CodeDom to compile the client proxy class.
CodeNamespace nmspace = new CodeNamespace (); Adds a namespace to the proxy class, which defaults to 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 save directly to the memory string.
TextWriter writer = File.createtext ("Test.cs"); Specify the name of the source code you want.
Provider. Generatecodefromcompileunit (unit, writer, null);
Writer. Flush ();
Writer. Close ();


If you invoke the "WebException: Request failed due to HTTP status 415: Unsupported Media Type. "Such an exception, then congratulate you and I as depressed, hurriedly put the server side of the WSE off." In the case where WSE must be used, the client needs to be adjusted, and the code needs to be written on your own. hehe ~ ~ ~

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.