您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > C/C++资料 > C# .NET 动态调用webservice的三种方式
动态调用webservice的三种方式多数时候我们通过添加Web引用...创建客户端代理类的方式调用WebService,但在某些情况下我们可能需要在程序运行期间动态调用一个未知的服务。在.NETFramework的System.Web.Services.Description命名空间中有我们需要的东西。具体步骤:1.从目标URL下载WSDL数据。2.使用ServiceDescription创建和格式化WSDL文档文件。3.使用ServiceDescriptionImporter创建客户端代理类。4.使用CodeDom动态创建客户端代理类程序集。5.利用反射调用相关WebService方法。上述步骤需要引用如下四个名称空间:usingSystem.Web.Services.Description;//WS的描述//以下几个用于根据描述动态生成代码并动态编译获取程序集usingSystem.CodeDom;usingMicrosoft.CSharp;usingSystem.CodeDom.Compiler;上述几个名称空间中包括如下几个重要的类:usingSystem.Web.Services.Description下:ServiceDescription//WS描述ServiceDescriptionImporter//通过描述生成客户端代理类,特别注意其中的Style以下是MSDN对其的描述:XMLWebservices的接口通常由Web服务描述语言(WSDL)文件来说明。例如,若要获取有关使用处公开的ASP.NET的Web服务的WSDL说明,只需导航到。使用ServiceDescriptionImporter类可以方便地将WSDL说明中包含的信息导入到System.CodeDom.CodeCompileUnit对象。通过调整Style参数的值,可以指示ServiceDescriptionImporter实例生成客户端代理类(通过透明调用该类可提供Web服务的功能)或生成抽象类(该类封装Web服务的功能而不实现该功能)。如果将Style属性设置为Client,则ServiceDescriptionImporter生成客户端代理类,通过调用这些类来提供说明的Web服务的功能。如果将Style属性设置为Server,则ServiceDescriptionImporter实例生成抽象类,这些类表示所说明的XMLWebservices的功能而不进行实现。然后,可以通过编写从这些抽象类继承的类来对其进行实现,并实现相关的方法。usingSystem.CodeDom下:CodedomUnit//它用于设定动态代码的名称空间,类名等,可以通过ServiceDescriptionImporter.Import()方法将WS的描述代码写入该类,以作动态编译用usingSystem.CodeDom.Compiler下:CodedomProvider//用于创建和检索代码生成器和代码编译器的实例,我们主要用到其实现子类CShareCodeProvider可以直接用CShareCodeProviderprovider=newCShareCodeProvider()来生成,或者用CodedomProvider.CreateProvider(CSharp)来生成ICodeCompiler//用于编译基于System.CodeDom的源代码表示形式。它通过CodedomProvider的CreateCompiler()方法来CompilerResults//表示从编译器返回的编译结果。它由ICodeCompiler根据指定的编译器设置从指定的CodeCompileUnit所包含的System.CodeDom树中编译程序集并返回。CompiledAssembly属性指示编译的程序集。了解如上信息后,就可动态调用WS了。OK,看看具体的例子。我们要调用的目标WebService,其URL是[WebService(Namespace==我的Web服务)][WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]publicclassWebService:System.Web.Services.WebService{publicWebService(){}[WebMethod]publicstringHelloWorld(){returnHelloWolrd!;}}1.动态调用WebService客户端动态调用代码usingSystem.IO;usingSystem.Net;usingSystem.Reflection;usingSystem.CodeDom;usingSystem.CodeDom.Compiler;usingSystem.Web.Services;usingSystem.Web.Services.Description;usingSystem.Web.Services.Protocols;usingSystem.Xml.Serialization;//1.使用WebClient下载WSDL信息。WebClientweb=newWebClient();Streamstream=web.OpenRead();//2.创建和格式化WSDL文档。ServiceDescriptiondescription=ServiceDescription.Read(stream);//3.创建客户端代理代理类。ServiceDescriptionImporterimporter=newServiceDescriptionImporter();importer.ProtocolName=Soap;//指定访问协议。importer.Style=ServiceDescriptionImportStyle.Client;//生成客户端代理。importer.CodeGenerationOptions=CodeGenerationOptions.GenerateProperties|CodeGenerationOptions.GenerateNewAsync;importer.AddServiceDescription(description,null,null);//添加WSDL文档。//4.使用CodeDom编译客户端代理类。CodeNamespacenmspace=newCodeNamespace();//为代理类添加命名空间,缺省为全局空间。CodeCompileUnitunit=newCodeCompileUnit();unit.Namespaces.Add(nmspace);ServiceDescriptionImportWarningswarning=importer.Import(nmspace,unit);CodeDomProviderprovider=CodeDomProvider.CreateProvider(CSharp);CompilerParametersparameter=newCompilerParameters();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);CompilerResultsresult=provider.CompileAssemblyFromDom(parameter,unit);//5.使用Reflection调用WebService。if(!result.Errors.HasErrors){Assemblyasm=result.CompiledAssembly;Typet=asm.GetType(WebService);//如果在前面为代理类添加了命名空间,此处需要将命名空间添加到类型前面。objecto=Activator.CreateInstance(t);MethodInfomethod=t.GetMethod(HelloWorld);Console.WriteLine(method.Invoke(o,null));}2.生成客户端代理程序集文件上面的代码通过在内存中创建动态程序集的方式完成了动态调用过程。如果我们希望将客户端代理类生成程序集文件保存到硬盘,则可以进行如下修改。生成程序集文件后,我们可以通过Assembly.LoadFrom()载入并进行反射调用。对于需要多次调用的系统,要比每次生成动态程序集效率高出很多。usingSystem.IO;usingSystem.Net;usingSystem.CodeDom;usingSystem.CodeDom.Compiler;usingSystem.Web.Services;usingSystem.Web.Services.Description;usingSystem.Web.Services.Protocols;usingSystem.Xml.Serialization;//1.使用WebClient下载WSDL信息。WebClientweb=newWebClient();Streamstream=web.OpenRead();//2.创建和格式化WSDL文档。ServiceDescriptiondescription=ServiceDescription.Read(stream);//3.创建客户端代理代理类。ServiceDescriptionImporterimporter=newServiceDescriptionImporter();importer.ProtocolName=Soap;//指定访问协议。importer.Style=ServiceDescriptionImportStyle.Client;//生成客户端代理。importer.CodeGenerationOptions=CodeGenerationOptions.GenerateProperties|CodeGenerationOptions.GenerateNewAsync;importer.AddServiceDescription(description,null,null);//添加WSDL文档。//4.使用CodeDom编译客户端代理类。CodeNamespacenmspace=newCodeNamespace();//为代理类添加命名空间,缺省为全局空间。CodeCompileUnitunit=newCodeCompileUnit();unit.Namespaces.Add(nmspace);ServiceDescriptionImportWarningswarning=importer.Import(nmspace,unit);CodeDomProviderprovi
本文标题:C# .NET 动态调用webservice的三种方式
链接地址:https://www.777doc.com/doc-7028359 .html