码迷,mamicode.com
首页 > Web开发 > 详细

Web Service学习笔记:动态调用WebService

时间:2014-12-12 10:08:26      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   io   ar   color   os   使用   

原文:Web Service学习笔记:动态调用WebService

多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我们可能需要在程序运行期间动态调用一个未知的服务。在 .NET Framework 的 System.Web.Services.Description 命名空间中有我们需要的东西。

具体步骤:

1. 从目标 URL 下载 WSDL 数据。
2. 使用 ServiceDescription 创建和格式化 WSDL 文档文件。
3. 使用 ServiceDescriptionImporter 创建客户端代理类。
4. 使用 CodeDom 动态创建客户端代理类程序集。
5. 利用反射调用相关 WebService 方法。

OK,看看具体的例子。

我们要调用的目标 WebService,其 URL 是 http://localhost:60436/Learn.WEB/WebService.asmx

 

 

bubuko.com,布布扣HelloWorld.asmx [WebService(Namespace = "http://www.rainsts.net/", Description="我的Web服务")]
bubuko.com,布布扣[WebServiceBinding(ConformsTo 
= WsiProfiles.BasicProfile1_1)]
bubuko.com,布布扣
public class WebService : System.Web.Services.WebService {
bubuko.com,布布扣
bubuko.com,布布扣
public WebService () {
bubuko.com,布布扣}

bubuko.com,布布扣
bubuko.com,布布扣  [WebMethod]
bubuko.com,布布扣  
public string HelloWorld()
bubuko.com,布布扣  
{
bubuko.com,布布扣    
return "Hello Wolrd!";
bubuko.com,布布扣  }

bubuko.com,布布扣}

bubuko.com,布布扣
bubuko.com,布布扣
1. 动态调用 WebService
bubuko.com,布布扣
bubuko.com,布布扣客户端动态调用代码
bubuko.com,布布扣
using System.IO;
bubuko.com,布布扣
using System.Net;
bubuko.com,布布扣
using System.Reflection;
bubuko.com,布布扣
using System.CodeDom;
bubuko.com,布布扣
using System.CodeDom.Compiler;
bubuko.com,布布扣
using System.Web.Services;
bubuko.com,布布扣
using System.Web.Services.Description;
bubuko.com,布布扣
using System.Web.Services.Protocols;
bubuko.com,布布扣
using System.Xml.Serialization;
bubuko.com,布布扣
bubuko.com,布布扣
// 1. 使用 WebClient 下载 WSDL 信息。
bubuko.com,布布扣
WebClient web = new WebClient();
bubuko.com,布布扣Stream stream 
= web.OpenRead("http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");
bubuko.com,布布扣
bubuko.com,布布扣
// 2. 创建和格式化 WSDL 文档。
bubuko.com,布布扣
ServiceDescription description = ServiceDescription.Read(stream);
bubuko.com,布布扣
bubuko.com,布布扣
// 3. 创建客户端代理代理类。
bubuko.com,布布扣
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
bubuko.com,布布扣
bubuko.com,布布扣importer.ProtocolName 
= "Soap"// 指定访问协议。
bubuko.com,布布扣
importer.Style = ServiceDescriptionImportStyle.Client; // 生成客户端代理。
bubuko.com,布布扣
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync; 
bubuko.com,布布扣
bubuko.com,布布扣importer.AddServiceDescription(description, 
nullnull); // 添加 WSDL 文档。
bubuko.com,布布扣
bubuko.com,布布扣
// 4. 使用 CodeDom 编译客户端代理类。
bubuko.com,布布扣
CodeNamespace nmspace = new CodeNamespace(); // 为代理类添加命名空间,缺省为全局空间。
bubuko.com,布布扣
CodeCompileUnit unit = new CodeCompileUnit();
bubuko.com,布布扣unit.Namespaces.Add(nmspace);
bubuko.com,布布扣
bubuko.com,布布扣ServiceDescriptionImportWarnings warning 
= importer.Import(nmspace, unit); 
bubuko.com,布布扣CodeDomProvider provider 
= CodeDomProvider.CreateProvider("CSharp");
bubuko.com,布布扣
bubuko.com,布布扣CompilerParameters parameter 
= new CompilerParameters();
bubuko.com,布布扣parameter.GenerateExecutable 
= false;
bubuko.com,布布扣parameter.GenerateInMemory 
= true;
bubuko.com,布布扣parameter.ReferencedAssemblies.Add(
"System.dll");
bubuko.com,布布扣parameter.ReferencedAssemblies.Add(
"System.XML.dll");
bubuko.com,布布扣parameter.ReferencedAssemblies.Add(
"System.Web.Services.dll");
bubuko.com,布布扣parameter.ReferencedAssemblies.Add(
"System.Data.dll");
bubuko.com,布布扣
bubuko.com,布布扣CompilerResults result 
= provider.CompileAssemblyFromDom(parameter, unit);
bubuko.com,布布扣
bubuko.com,布布扣
// 5. 使用 Reflection 调用 WebService。
bubuko.com,布布扣
if (!result.Errors.HasErrors)
bubuko.com,布布扣
{
bubuko.com,布布扣  Assembly asm 
= result.CompiledAssembly;
bubuko.com,布布扣  Type t 
= asm.GetType("WebService"); // 如果在前面为代理类添加了命名空间,此处需要将命名空间添加到类型前面。
bubuko.com,布布扣

bubuko.com,布布扣  
object o = Activator.CreateInstance(t);
bubuko.com,布布扣  MethodInfo method 
= t.GetMethod("HelloWorld");
bubuko.com,布布扣  Console.WriteLine(method.Invoke(o, 
null));
bubuko.com,布布扣}

bubuko.com,布布扣

 

 

2. 生成客户端代理程序集文件

上面的代码通过在内存中创建动态程序集的方式完成了动态调用过程。如果我们希望将客户端代理类生成程序集文件保存到硬盘,则可以进行如下修改。生成程序集文件后,我们可以通过 Assembly.LoadFrom() 载入并进行反射调用。对于需要多次调用的系统,要比每次生成动态程序集效率高出很多。

 

 

bubuko.com,布布扣using System.IO;
bubuko.com,布布扣
using System.Net;
bubuko.com,布布扣
using System.CodeDom;
bubuko.com,布布扣
using System.CodeDom.Compiler;
bubuko.com,布布扣
using System.Web.Services;
bubuko.com,布布扣
using System.Web.Services.Description;
bubuko.com,布布扣
using System.Web.Services.Protocols;
bubuko.com,布布扣
using System.Xml.Serialization;
bubuko.com,布布扣
bubuko.com,布布扣
// 1. 使用 WebClient 下载 WSDL 信息。
bubuko.com,布布扣
WebClient web = new WebClient();
bubuko.com,布布扣Stream stream 
= web.OpenRead("http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");
bubuko.com,布布扣
bubuko.com,布布扣
// 2. 创建和格式化 WSDL 文档。
bubuko.com,布布扣
ServiceDescription description = ServiceDescription.Read(stream);
bubuko.com,布布扣
bubuko.com,布布扣
// 3. 创建客户端代理代理类。
bubuko.com,布布扣
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
bubuko.com,布布扣
bubuko.com,布布扣importer.ProtocolName 
= "Soap"// 指定访问协议。
bubuko.com,布布扣
importer.Style = ServiceDescriptionImportStyle.Client; // 生成客户端代理。
bubuko.com,布布扣
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync; 
bubuko.com,布布扣
bubuko.com,布布扣importer.AddServiceDescription(description, 
nullnull); // 添加 WSDL 文档。
bubuko.com,布布扣
bubuko.com,布布扣
// 4. 使用 CodeDom 编译客户端代理类。
bubuko.com,布布扣
CodeNamespace nmspace = new CodeNamespace(); // 为代理类添加命名空间,缺省为全局空间。
bubuko.com,布布扣
CodeCompileUnit unit = new CodeCompileUnit();
bubuko.com,布布扣unit.Namespaces.Add(nmspace);
bubuko.com,布布扣
bubuko.com,布布扣ServiceDescriptionImportWarnings warning 
= importer.Import(nmspace, unit); 
bubuko.com,布布扣CodeDomProvider provider 
= CodeDomProvider.CreateProvider("CSharp");
bubuko.com,布布扣
bubuko.com,布布扣CompilerParameters parameter 
= new CompilerParameters();
bubuko.com,布布扣parameter.GenerateExecutable 
= false;
bubuko.com,布布扣parameter.OutputAssembly 
= "test.dll"// 可以指定你所需的任何文件名。
bubuko.com,布布扣
parameter.ReferencedAssemblies.Add("System.dll");
bubuko.com,布布扣parameter.ReferencedAssemblies.Add(
"System.XML.dll");
bubuko.com,布布扣parameter.ReferencedAssemblies.Add(
"System.Web.Services.dll");
bubuko.com,布布扣parameter.ReferencedAssemblies.Add(
"System.Data.dll");
bubuko.com,布布扣
bubuko.com,布布扣CompilerResults result 
= provider.CompileAssemblyFromDom(parameter, unit);
bubuko.com,布布扣
if (result.Errors.HasErrors)
bubuko.com,布布扣
{
bubuko.com,布布扣  
// 显示编译错误信息
bubuko.com,布布扣
}

bubuko.com,布布扣
bubuko.com,布布扣调用程序集文件演示
bubuko.com,布布扣Assembly asm 
= Assembly.LoadFrom("test.dll");
bubuko.com,布布扣Type t 
= asm.GetType("WebService"); 
bubuko.com,布布扣
bubuko.com,布布扣
object o = Activator.CreateInstance(t);
bubuko.com,布布扣MethodInfo method 
= t.GetMethod("HelloWorld");
bubuko.com,布布扣Console.WriteLine(method.Invoke(o, 
null));
bubuko.com,布布扣

 

 

3. 获取客户端代理类源代码

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

 

 

bubuko.com,布布扣using System.IO;
bubuko.com,布布扣
using System.Net;
bubuko.com,布布扣
using System.CodeDom;
bubuko.com,布布扣
using System.CodeDom.Compiler;
bubuko.com,布布扣
using System.Web.Services;
bubuko.com,布布扣
using System.Web.Services.Description;
bubuko.com,布布扣
using System.Web.Services.Protocols;
bubuko.com,布布扣
using System.Xml.Serialization;
bubuko.com,布布扣
bubuko.com,布布扣
// 1. 使用 WebClient 下载 WSDL 信息。
bubuko.com,布布扣
WebClient web = new WebClient();
bubuko.com,布布扣Stream stream 
= web.OpenRead("http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");
bubuko.com,布布扣
bubuko.com,布布扣
// 2. 创建和格式化 WSDL 文档。
bubuko.com,布布扣
ServiceDescription description = ServiceDescription.Read(stream);
bubuko.com,布布扣
bubuko.com,布布扣
// 3. 创建客户端代理代理类。
bubuko.com,布布扣
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
bubuko.com,布布扣
bubuko.com,布布扣importer.ProtocolName 
= "Soap"// 指定访问协议。
bubuko.com,布布扣
importer.Style = ServiceDescriptionImportStyle.Client; // 生成客户端代理。
bubuko.com,布布扣
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync; 
bubuko.com,布布扣
bubuko.com,布布扣importer.AddServiceDescription(description, 
nullnull); // 添加 WSDL 文档。
bubuko.com,布布扣
bubuko.com,布布扣
// 4. 使用 CodeDom 编译客户端代理类。
bubuko.com,布布扣
CodeNamespace nmspace = new CodeNamespace(); // 为代理类添加命名空间,缺省为全局空间。
bubuko.com,布布扣
CodeCompileUnit unit = new CodeCompileUnit();
bubuko.com,布布扣unit.Namespaces.Add(nmspace);
bubuko.com,布布扣
bubuko.com,布布扣ServiceDescriptionImportWarnings warning 
= importer.Import(nmspace, unit); 
bubuko.com,布布扣CodeDomProvider provider 
= CodeDomProvider.CreateProvider("CSharp");
bubuko.com,布布扣
bubuko.com,布布扣
// 5. 保存源代码到文件。当然,你也可以直接保存到内存字符串中。
bubuko.com,布布扣
TextWriter writer = File.CreateText("test.cs"); // 指定你所需的源代码文件名。
bubuko.com,布布扣
provider.GenerateCodeFromCompileUnit(unit, writer, null);
bubuko.com,布布扣writer.Flush();
bubuko.com,布布扣writer.Close();
bubuko.com,布布扣
bubuko.com,布布扣

 

如果你调用时触发 "WebException: 请求因 HTTP 状态 415 失败: Unsupported Media Type。" 这样的异常,那么恭喜你和我一样郁闷,赶紧把服务器端的 WSE 关掉吧。在必须使用 WSE 的情况下,需要对客户端进行调整.

Web Service学习笔记:动态调用WebService

标签:des   style   blog   http   io   ar   color   os   使用   

原文地址:http://www.cnblogs.com/lonelyxmas/p/4159061.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!