Three ways to dynamically invoke WebService __web

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

Three ways to dynamically invoke WebService

Most of the time we "add Web references ..." The client proxy class is created in a way that calls WebService, but in some cases we may need to dynamically invoke an unknown service 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 target URL.
2. Use ServiceDescription to create and format WSDL document files.
3. Create the client proxy class using ServiceDescriptionImporter.
4. Dynamically create client proxy class assemblies using CodeDom.
5. Invoke the relevant WebService method using reflection.

The above steps need to refer to the following four namespaces:

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

The following several are used to dynamically generate code based on the description and to dynamically compile the fetch assembly

Using System.CodeDom;

Using Microsoft.csharp;

Using System.CodeDom.Compiler;

The following several important classes are included in the above namespaces:

Using System.Web.Services.Description:

ServiceDescription//WS Description

ServiceDescriptionImporter///Generate client proxy class by description, pay special attention to the style

The following is a description of MSDN for this:

Interfaces for Xmlweb services are typically described by Web Services Description Language (WSDL) files. For example, to get a WSDL description of a asp.net Web service that is exposed using http://localhost/service.asmx, simply navigate to Http://localhost/service.asmx?WSDL. The ServiceDescriptionImporter class makes it easy to import information contained in a WSDL description into a 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 and does not implement it. If you set the Style property to client, ServiceDescriptionImporter generates client proxy classes that provide the functionality of the described WEB service by calling these classes. If you set the Style property to Server, the ServiceDescriptionImporter instance generates abstract classes that represent the functionality of the XML WEB services described and do not implement them. You can then implement them by writing classes that inherit from these abstract classes, and implement related methods.

Using system.codedom:

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

Using 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 using Csharecodeproviderprovider=new Csharecodeprovider (), or Codedomprovider.createprovider ("CSharp") to generate

ICodeCompiler//For compiling source code representations based on System.CodeDom.

It uses the CodeDomProvider CreateCompiler () method to

CompilerResults//Represents the result of the compilation returned from the compiler. It compiles and returns the assembly from the System.CodeDom tree contained in the specified CodeCompileUnit, based on the compiler settings specified by ICodeCompiler. The Compiledassembly property indicates the compiled assembly.

Once you know the information, you can invoke WS dynamically.


OK, look at the specific example.

We want 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 WSDL documents.
ServiceDescription Description = Servicedescription.read (stream);

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

Importer. ProtocolName = "Soap"; Specifies the Access protocol.
Importer. Style = servicedescriptionimportstyle.client; Generate the client proxy.
Importer. CodeGenerationOptions = Codegenerationoptions.generateproperties | Codegenerationoptions.generatenewasync;

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

4. Use 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. Use Reflection to invoke WebService.
if (!result. Errors.haserrors)
{
Assembly asm = result.compiledassembly;
Type t = asm. GetType ("WebService"); If you added a namespace to the proxy class earlier, you would need to 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 Client Agent assembly files

The above code completes the dynamic invocation process by creating a dynamic assembly in memory. If we want to save the client proxy class build assembly file to a hard disk, you can make the following modifications. After the assembly file is generated, 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 at a 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 WSDL documents.
ServiceDescription Description = Servicedescription.read (stream);

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

Importer. ProtocolName = "Soap"; Specifies the Access protocol.
Importer. Style = servicedescriptionimportstyle.client; Generate the client proxy.
Importer. CodeGenerationOptions = Codegenerationoptions.generateproperties | Codegenerationoptions.generatenewasync;

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

4. Use 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 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)
{
displaying compilation error messages
}


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

There is also a situation where we need to get 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 WSDL information.
WebClient Web = new WebClient ();
Stream Stream =web. OpenRead ("Http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");

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

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

Importer. ProtocolName = "Soap"; Specifies the Access protocol.
Importer. Style = servicedescriptionimportstyle.client; Generate the client proxy.
Importer. CodeGenerationOptions = Codegenerationoptions.generateproperties | Codegenerationoptions.generatenewasync;

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

4. Use 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 source code to file. Of course, you can also save it directly into the memory string.
TextWriter writer = File.createtext ("Test.cs"); Specify the source code file name you want.
Provider. Generatecodefromcompileunit (unit, writer, null);
Writer. Flush ();
Writer. Close ();


If you invoke the trigger "WebException: Request failed for HTTP status 415: Unsupported Media Type." "Such an exception, then congratulate you and I as depressed, hurriedly turn off the server-side WSE." In cases where WSE must be used, the client needs to be adjusted, and the code needs to be written by yourself. 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.