Make dynamic calls with C # through reflection WebService farewell Web Reference (reprint)

Source: Internet
Author: User

As we all know, calling WebService can make Web references to WebService addresses in the project, but this is really inconvenient. I want to be able to use configuration files to call WebService flexibly. How to achieve it?

Dynamic call WebService by reflection in C #

Here is the WebService code:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingsystem.web;usingSystem.Web.Services;namespacetestwebservice{/// <summary>    ///Summary description of Service1/// </summary>[WebService (Namespace ="http://tempuri.org/", description="My Web service")] [WebServiceBinding (ConformsTo=Wsiprofiles.basicprofile1_1)] [System.ComponentModel.ToolboxItem (false)]    //to allow the Web service to be called from the script using ASP. NET AJAX, uncomment the downstream. //[System.Web.Script.Services.ScriptService]     Public classTestWebService:System.Web.Services.WebService {[WebMethod] Public stringHelloWorld () {return "Test Hello World"; } [WebMethod] Public stringTest () {return "Testing Test"; } [WebMethod (CacheDuration= -, Description ="Test")]         PublicList<string>getpersons () {List<String> list =Newlist<string>(); List. ADD ("Test a"); List. ADD ("Test Two"); List. ADD ("Test Three"); returnlist; }      }}

Here is the code for the client:

usingSystem.Text;usingSystem.Net;usingSystem.IO;usingSystem.Web.Services.Description;usingsystem.codedom;usingMicrosoft.csharp;usingSystem.CodeDom.Compiler;usingSystem;namespacetestcommon{ Public classWebservice {/// <summary>        ///Instantiate WebServices/// </summary>        /// <param name= "url" >webservices Address</param>        /// <param name= "methodname" >method to invoke</param>        /// <param name= "args" >Put the parameters needed in the webservices in order in this object[]</param>         Public Static ObjectInvokewebservice (stringUrlstringMethodNameObject[] args) {            //the namespace here is the namespace of the webservices to be referenced, which I have not changed or can use. You can also add a parameter from the outside to pass in.             string@namespace ="Client"; Try            {                //get WSDLWebClient WC =NewWebClient (); Stream Stream= WC. OpenRead (URL +"? WSDL"); ServiceDescription SD=Servicedescription.read (stream); stringclassname = sd. services[0].                Name; ServiceDescriptionImporter SDI=NewServiceDescriptionImporter (); Sdi. Addservicedescription (SD,"",""); CodeNamespace cn=NewCodeNamespace (@namespace); //Generate the client proxy class codeCodeCompileUnit CCU =NewCodeCompileUnit (); Ccu.                Namespaces.add (CN); Sdi.                Import (CN, CCU); CSharpCodeProvider csc=NewCSharpCodeProvider (); //ICodeCompiler ICC = csc.                                CreateCompiler (); //Setting Compilation ParametersCompilerParameters cplist =NewCompilerParameters (); Cplist. GenerateExecutable=false;//a dynamically compiled assembly does not generate an executable fileCplist. GenerateInMemory =true;//The dynamically compiled assembly exists only in memory and not on the hard disk fileCplist. Referencedassemblies.add ("System.dll"); Cplist. Referencedassemblies.add ("System.XML.dll"); Cplist. Referencedassemblies.add ("System.Web.Services.dll"); Cplist. Referencedassemblies.add ("System.Data.dll"); //Compiling proxy classesCompilerResults CR =csc.compileassemblyfromdom (cplist, CCU); if(true==Cr. errors.haserrors) {System.Text.StringBuilder sb=NewSystem.Text.StringBuilder (); foreach(System.CodeDom.Compiler.CompilerError CEinchCr. Errors) {sb. Append (CE.                        ToString ()); Sb.                    Append (System.Environment.NewLine); }                    Throw NewException (sb.)                ToString ()); }                //build the proxy instance and call the methodSystem.Reflection.Assembly Assembly =cr.compiledassembly; Type T= assembly. GetType (@namespace +"."+ ClassName,true,true); Objectobj =activator.createinstance (t); System.Reflection.MethodInfo mi=T.getmethod (methodname); //Note: method. Invoke (o, NULL) returns an object, and if your server returns a DataSet, here is also the (dataset) method. Invoke (o, null) just a turn, method. Invoke (0,null) Here the null can be passed to invoke the parameters required by the method, string[] form of the                returnmi.            Invoke (obj, args); }            Catch            {                return NULL; }        }    }    classProgram {Static voidMain (string[] args) {            stringURL ="Http://localhost:3182/Service1.asmx?WSDL";//This address can be written in the config file, which will be taken out. Add the following to the original address:? WSDL            stringMETHOD ="getpersons"; String[] Item= (string[]) webservice.invokewebservice (URL, method,NULL); foreach(stringStrinchItem)        Console.WriteLine (str); }    }}

Note: The code above requires 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;

The code is relatively simple, why can it be called? Dynamically compiled with reflection to read and execute. It may be helpful to know how reflection and reflection are to you.

Reflection provides objects (type types) that encapsulate assemblies, modules, and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and call its methods or access its fields and properties. For more information, see: https://msdn.microsoft.com/zh-cn/library/ms173183 (vs.80). aspx

Why WebServices can be achieved by reflection?

WebService is described through WSDL (using the SOAP protocol) during transmission. Therefore, we need to obtain the WSDL description of the WebService and use that description to dynamically generate the assembly. It then gets the newly generated assembly through reflection and calls its methods!

The following is a description of MSDN:

The interfaces of XML Web services 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.

For the configuration parameters of CompilerParameters in the code above, the following instructions are available:

CodeDom can dynamically compile code code into an assembly, sometimes we just want to dynamically compile the assembly, called in memory or on the hard disk, which is the CodeDom dynamic compilation. Microsoft provides a dynamic compiler in the CodeDom, which is where the ICodeCompiler comes in, which defines the interface used to invoke source code compilation or the CodeDom tree using the specified compiler. You can generate a reference object from CodeDomProvider: Codedomprovider.createprovider (""). CreateCompiler ();

The methods that we provide for assembly compilation in ICodeCompiler are:

CompileAssemblyFromDom: Compiles the assembly from the System.CodeDom tree contained in the specified CodeCompileUnit using the specified compiler settings.

Compileassemblyfromdombatch: Compiles the assembly using the specified compiler settings, based on the system.codedom tree contained in the specified array of CodeCompileUnit objects.

Compileassemblyfromfile: Compiles an assembly from the source code contained in the specified file, using the specified compiler settings.

Compileassemblyfromfilebatch: Compiles an assembly from the source code contained in the specified file, using the specified compiler settings.

CompileAssemblyFromSource: Compiles the assembly from the specified string that contains the source code, using the specified compiler settings.

Compileassemblyfromsourcebatch: Compiles the assembly from the specified array of strings that contain the source code, using the specified compiler settings.

In our CodeDomProvider also provides CompileAssemblyFromDom, Compileassemblyfromfile, CompileAssemblyFromSource.

At the time of their compilation There is a Variant parameter CompilerParameters, which provides compile-time parameter options:

CompilerOptions: Gets or sets an optional additional command-line argument string to use when invoking the compiler.

Embeddedresources: Gets the. NET Framework resource files to include when compiling the assembly output.

Evidence: Specifies an evidence object that represents the security policy permissions to be granted to the compiled assembly.

GenerateExecutable: Gets or sets a value that indicates whether the executable file is built.

GenerateInMemory: Gets or sets a value that indicates whether the output is generated in memory.

IncludeDebugInformation: Gets or sets a value that indicates whether debugging information is included in the compiled executable file.

Linkedresources: Gets the. NET Framework resource file referenced in the current source.

MainClass: Gets or sets the name of the main class.

OutputAssembly: Gets or sets the name of the output assembly.

ReferencedAssemblies: Gets the assembly referenced by the current project.

Tempfiles: Gets or sets the collection that contains the temporary files.

TreatWarningsAsErrors: Gets or sets a value that indicates whether the warning is treated as an error.

Usertoken: Gets or sets the user token that is used when the compiler process is created.

WarningLevel: Gets or sets the warning level that causes the compiler to abort compilation.

Win32Resource: Gets or sets the file name of the WIN32 resource file to link to the compiled assembly.

Their results return the compilation result CompilerResults, which provides the compilation result information:

compiledassembly: Gets or sets the compiled assembly.

Errors: Gets a collection of compiler errors and warnings.

Evidence: Indicates the evidence object that represents the security policy permission for the compiled assembly.

Nativecompilerreturnvalue: Gets or sets the return value of the compiler.

Output: Gets the compiler output message.

pathtoassembly: Gets or sets the path of the compiled assembly.

Tempfiles: Gets or sets the collection of temporary files to use.

Original Link 1

Original Link 2

Make dynamic calls with C # through reflection WebService farewell Web Reference (reprint)

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.