C# NET 动态调用webservice的三种方式之欧阳术创编.docx

上传人:b****7 文档编号:11389094 上传时间:2023-02-28 格式:DOCX 页数:7 大小:18.41KB
下载 相关 举报
C# NET 动态调用webservice的三种方式之欧阳术创编.docx_第1页
第1页 / 共7页
C# NET 动态调用webservice的三种方式之欧阳术创编.docx_第2页
第2页 / 共7页
C# NET 动态调用webservice的三种方式之欧阳术创编.docx_第3页
第3页 / 共7页
C# NET 动态调用webservice的三种方式之欧阳术创编.docx_第4页
第4页 / 共7页
C# NET 动态调用webservice的三种方式之欧阳术创编.docx_第5页
第5页 / 共7页
点击查看更多>>
下载资源
资源描述

C# NET 动态调用webservice的三种方式之欧阳术创编.docx

《C# NET 动态调用webservice的三种方式之欧阳术创编.docx》由会员分享,可在线阅读,更多相关《C# NET 动态调用webservice的三种方式之欧阳术创编.docx(7页珍藏版)》请在冰豆网上搜索。

C# NET 动态调用webservice的三种方式之欧阳术创编.docx

C#NET动态调用webservice的三种方式之欧阳术创编

动态调用webservice的三种方式

时间:

2021.02.02

创作:

欧阳术

多数时候我们通过"添加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)文件来说明。

例如,若要获取有关使用http:

//localhost/service.asmx处公开的ASP.NET的Web服务的WSDL说明,只需导航到http:

//localhost/service.asmx?

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是http:

//localhost:

60436/Learn.WEB/WebService.asmx

HelloWorld.asmx

[WebService(Namespace="Description="我的Web服务")]

[WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]

publicclassWebService:

System.Web.Services.WebService{

 publicWebService(){

 }

  [WebMethod]

  publicstringHelloWorld()

  {

    return"HelloWolrd!

";

  }

}

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("http:

//localhost:

60436/Learn.WEB/WebService.asmx?

WSDL");

//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("http:

//localhost:

60436/Learn.WEB/WebService.asmx?

WSDL");

//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.OutputAssembly="test.dll";//可以指定你所需的任何文件名。

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);

if(result.Errors.HasErrors)

{

  //显示编译错误信息

}

调用程序集文件演示

Assemblyasm=Assembly.LoadFrom("test.dll");

Typet=asm.GetType("WebService");

objecto=Activator.CreateInstance(t);

MethodInfomethod=t.GetMethod("HelloWorld");

Console.WriteLine(method.Invoke(o,null));

3.获取客户端代理类源代码还有一种情形,就是我们需要获得客户端代理类的C#源代码。

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("http:

//localhost:

60436/Learn.WEB/WebService.asmx?

WSDL");

//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");

//5.保存源代码到文件。

当然,你也可以直接保存到内存字符串中。

TextWriterwriter=File.CreateText("test.cs");//指定你所需的源代码文件名。

provider.GenerateCodeFromCompileUnit(unit,writer,null);

writer.Flush();

writer.Close();

如果你调用时触发"WebException:

请求因HTTP状态415失败:

UnsupportedMediaType。

"这样的异常,那么恭喜你和我一样郁闷

,赶紧把服务器端的WSE关掉吧。

在必须使用WSE的情况下,需要对客户端进行调整,至于代码需要你自己去写了。

呵呵~~~~

时间:

2021.02.02

创作:

欧阳术

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1