澳门新葡萄京官网注册 2

澳门新葡萄京官网注册Web Service-使用

  • Web
    Service-介绍
  • Web
    Service-创建
  • Web Service-使用
  • Web
    Service-支持的数据类型
  • Web
    Service-安全

1. 有关生存期的补充
正常情况下,每次调用 WebMethod,服务器都会创建一个新的 WebService
对象,即便客户端使用同一个代理对象多次调用 WebMethod。
而我们一旦调用了有缓存标记的 WebMethod,只要未超出缓存期,WebService
对象都不会被重新创建。在缓存期内调用没有缓存标记的
WebMethod,也会继续使用该 WebService
对象。有太多因素让这个缓存机制变得不那么可靠,因此我们不能奢望用缓存标记来维持特定的对象状态,况且缓存机制的设计初衷也只是为了快速输出那些比较稳定非常大的数据。
基于多用户并发调用这个环境,WebService
本身最好设计成无状态对象,我们可以使用 Session 和 Application
来保持特定的状态信息。
2. 异步调用
网上很多人在写有关 .net 2.0 的文章时,都喜欢用“优雅”这个词。的确,在 2.0
中编译器和代码生成器为我们封装了很多罗嗦的东西,诸如匿名方法、委托推断等等,当然还有这
WebService 的异步调用。我们不用再写那些个 BeginXXX、EndXXX
了,基于事件驱动的异步机制会自动为每个 WebMethod 生成一个 XXXAsync
的异步方法和 XXXCompleted
事件,我们只需调用该方法,并处理该事件即可完成异步操作,当真是优雅了不少。不要小看
2.0 的这些封装,我们编写的代码越少意味着出错的几率越小。
下面的示例中,我们使用了匿名方法来处理事件,看上去更简洁了些。
WebServices.cs

原文引自:


[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
   [WebMethod]
   public string HelloWorld()
   {
     return “Hello World!”;
   }
}

这几天看了下WS访问验证的文章,发现这个写的不错,就收藏了,留着备用。嘿嘿

(在现在的版本中,通过在解决方案上右键,选择 Add
Web Reference,输入 Web Service 地址,即可直接使用该 Web Service。请参见
Add Web Reference 与 Add Service Reference
的使用区别。)

Client.cs

解决方案一:通过通过SOAP Header身份验证。

前面创建了一个简单的 Web Service,但如何使用它呢?

WebService ws = new WebService();
ws.HelloWorldCompleted += delegate(object sender,
HelloWorldCompletedEventArgs e)
{
   Console.WriteLine(e.Result);
};
ws.HelloWorldAsync(“xxx”);

1.我们实现一个用于身份验证的类,文件名MySoapHeader.cs

首先创建一个 Web Service,代码如下:

3. 缓存
WebMethodAttribute.CacheDuration 为 WebService
提供了缓存申明机制。通过添加该标记,我们可以缓存输出结果。不过缓存机制会影响
WebService 的生存期(见上)。
WebServices.cs

MySoapHeader类继承自System.Web.Services.Protocols.SoapHeader。且定义了两个成员变量,UserName和PassWord,还定义了一个用户认证的函数ValideUser。它提供了对UserName和PassWord检查的功能

<%@ WebService Language=”C#” Class=”WebService” %>

[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
   [WebMethod(CacheDuration=10)]
   public DateTime TestCache()
   {
     return DateTime.Now;
   }
}

 

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

Client.cs

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.Services;
using System.Web.Services.Protocols;
/// <summary>
///MySoapHeader 的摘要说明
/// </summary>
public class MySoapHeader:SoapHeader
{
    public MySoapHeader()
    {
        //
        //TODO: 在此处添加构造函数逻辑
        //
    }
    public string UserName;
    public string PassWord;
    public bool ValideUser(string in_UserName, string in_PassWord)   
    {
        if ((in_UserName == “zxq”) && (in_PassWord == “123456”))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

[WebService(Namespace = “]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService  : System.Web.Services.WebService
{
    [WebMethod]
    public string HelloWorld(string userName)
    {
        return “Hello World” + userName;
    }
}

WebService ws = new WebService();
for (int i = 0; i < 20; i++)
{
   Console.WriteLine(“{0}:{1}”, i + 1, ws.TestCache());
   Thread.Sleep(1000);
}

 

我们在访问 Web Service 网页时,添加上参数
WSDL,比如下例地址:

4. 保持状态
.NET WebService 是建立在 ASP.NET 基础上,在 WebService
中我们同样可以访问 Session、User、Application
等上下文对象,不过在某些使用细节上可能有所不同。
由于 WebService 客户端代理对象可能应用于 ConsoleApplication、WinForm 或
WebForm 等环境,而 Session 又必须通过 Cookie 来保存唯一的
SessionID,因此我们必须使用 CookieContainer 创建 Cookie 容器来保存
WebService 返回的 Session 信息,否则每次调用的 SessionID
都不同,自然无法使用 Session 来保存状态了。
创建容器对象后,必须将其引用赋值给代理对象的 CookieContainer
属性。在第一次调用 SessionEnabled WebMethod 后,该容器将持有 Session
Cookie 信息。如果需要在多个代理对象中调用 SessionEnabled
WebMethod,那么它们必须持有同一个 Cookie 容器对象。
WebServices.cs

 

[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
   [WebMethod(EnableSession = true)]
   public string TestSession()
   {
     string s = “TestSession”;
     object o = Session[s];
     int i = o != null ? (int)o : 0;
     ++i;
     Session[s] = i;
     return Session.SessionID.ToString() + “:” + i;
   }
}

2.下面我们创建WebService.asmx    WebService.cs代码如下:

可以得到一个 XML 文件:

Client.cs

 

澳门新葡萄京官网注册 1

WebService ws = new WebService();
// 创建Cookie容器,保持SessionID。否则每次调用的 SessionID 都不同。
CookieContainer cookies = new CookieContainer();
ws.CookieContainer = cookies;
for (int i = 0; i < 10; i++)
{
   Console.WriteLine(“{0}:{1}”, i + 1, ws.TestSession());
}

using System;
using System.Collections;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

我们现在要把这个 XML 文件生成 .cs 文件

至于 Application 的使用和 WebForm 中基本没有什么区别。
WebServices.cs

/// <summary>
///WebService 的摘要说明
/// </summary>
[WebService(Namespace = “]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{

使用 WSDL 文件,该文件是 .NET Framework SDK 的一部分,通常位于类似于

[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
   [WebMethod]
   public DateTime TestApplicationState()
   {
     object o = Application[“TestApplicationState”];
     if (o == null)
     {
       o = DateTime.Now;
       Application[“TestApplicationState”] = o;
     }
     return (DateTime)o;
   }
}

    public WebService()
    {

C:Program FilesMicrosoft Visual Studio 8SDKv2.0Bin

Client.cs

        //如果使用设计的组件,请取消注释以下行 
        //InitializeComponent(); 
    }
    public MySoapHeader header; ////定义用户身份验证类变量header
    [WebMethod(Description = “用户验证测试”)]
    [System.Web.Services.Protocols.SoapHeader(“header”)]//用户身份验证的soap头 
    public string HelloWorld(string contents)
    {
        //验证是否有权访问 
        if (header.ValideUser(header.UserName, header.PassWord))
        {
            return contents + “执行了”;
        }
        else
        {
            return “您没有权限访问”;
        }
    }
}

的地方。在命令提示符中使用类似如下的命令生成 .cs 文件:

for (int i = 0; i < 10; i++)
{
   WebService ws = new WebService();
   Console.WriteLine(“{0}:{1}”, i + 1, ws.TestApplicationState());
   Thread.Sleep(1000);
}

 

C:Program FilesMicrosoft Visual Studio 8SDKv2.0Bin>wsdl
/language:C#
/namespace:cftea /out:D:WebService.cs

5. SoapHeader
SoapHeader
多数情况下用来传递用户身份验证信息,当然它的作用远不止如此,有待于在实际应用中发掘。
SoapHeader 缺省情况下由客户端代理对象发送给 WebService,当然我们可以通过
WebMethodAttribute.Direction 来改变传送方向。
SoapHeader 使用步骤:
(1) 创建继承自 System.Web.WebServices.SoapHeader 的自定义 SoapHeader
类型。
(2) 在 WebService 中创建拥有 public 访问权限的自定义 SoapHeader 字段。
(3) 在需要使用 SoapHeader 的 WebMethod 上添加 SoapHeaderAttribute
访问特性。SoapHeaderAttribute 构造必须指定 memberName
参数,就是我们在第二步中申明的字段名称。
(4) 生成器会自动为客户端生成同名的自定义 SoapHeader
类型,只不过比起我们在 WebService
端创建的要复杂一些。同时还会为代理类型添加一个 soapheaderValue 属性。
在下面的演示代码,客户端将传递一个自定义 MyHeader 到
WebService。请注意,我们尽管在 WebService 中申明了 MyHeader
字段,但并没有创建对象实例,这是因为客户端传递过来的 XML 中包含了
SoapHeader 信息,基础结构会自动解析并创建对象实例,然后赋值给 my
字段。至于客户端,自然需要创建一个 MyHeader 对象实例,并赋值给
WebService.MyHeaderValue 属性。SoapHeaderAttribute.Direction 缺省就是
In,下面例子中的 “Direction = SoapHeaderDirection.In” 可以省略。
WebServices.cs

 

language 指定语言,namespace 指定名称空间,out 指定输出位置。

public class MyHeader : SoapHeader
{
   public string Username;
   public string Password;
}
[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
   public MyHeader my;
   [WebMethod]
   [SoapHeader(“my”, Direction = SoapHeaderDirection.In)]
   public void TestSoapHeadIn()
   {
     System.Diagnostics.Debug.Write(my.Username);
     System.Diagnostics.Debug.Write(my.Password);
   }
}

 3.客户端 创建个Default.aspx

然后将这个 .cs
文件交给另一个服务器端的程序员,另一个服务器端的程序员就可以根据这个 .cs
文件来创建对本 Web Service 的调用,将 .cs 文件放在 App_Code 下。

Client.cs

Default.aspx .cs代码

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using cftea;
public partial class Default2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        WebService ws = new WebService();
        lbl.Text =
ws.HelloWorld(“千一网络”);
    }
}

WebService ws = new WebService();
MyHeader head = new MyHeader();
head.Username = “u2”;
head.Password = “p2”;
ws.MyHeadValue = head;
ws.TestSoapHeadIn();

 

预览,我们就可以看到经过 Web Service 处理后返回的结果了。

我们改写一下,将传递方向改为从 WebService 到客户端。自然我们需要调整
“Direction = SoapHeaderDirection.Out”,在 WebMethod 中我们还必须创建
MyHeader 实例,因为这次我们不会接受到客户端传递的 SoapHeader
了。客户端代理对象调用 WebMethod 后就可以使用 MyHeaderValue
属性访问其内容了。
WebServices.cs

using System;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

说明:我们也可以将 .cs 文件编译成 dll,再将
dll 放在 bin 目录下。请参见 将 CS 编译成 DLL,并利用 Namespace
使用之。

public class MyHeader : SoapHeader
{
   public string Username;
   public string Password;
}
[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
   public MyHeader my;
   [WebMethod]
   [SoapHeader(“my”, Direction = SoapHeaderDirection.Out)]
   public void TestSoapHeadOut()
   {
     my = new MyHeader();
     my.Username = “u1”;
     my.Password = “p1”;
   }
}

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        com.cn1yw.WebService test = new com.cn1yw.WebService();//web引用(改成您自己的)
        com.cn1yw.MySoapHeader Header = new com.cn1yw.MySoapHeader();//web引用创建soap头对象(改成您自己的)
        //设置soap头变量
        Header.UserName = “zxq”;
        Header.PassWord = “123456”;
        test.MySoapHeaderValue = Header;
        //调用web 方法
        Response.Write(test.HelloWorld(“我是强”));
    }
}

  • Web
    Service-介绍
  • Web
    Service-创建
  • Web Service-使用
  • Web
    Service-支持的数据类型
  • Web
    Service-安全

Client.cs

 


WebService ws = new WebService();
ws.TestSoapHeadOut();
Console.WriteLine(ws.MyHeaderValue.Username);
Console.WriteLine(ws.MyHeaderValue.Password);

解决方案二:通过集成windows身份验证。

6. 异常
ASP.NET WebService 通过 Fault XML
元素来传递异常信息,客户端代理对象会生成一个 SoapException
的异常,并使用 Fault XML 信息填充其相关属性,诸如 Message
等。另外我们可以对 WebService 进行异常包装,除了传递 Exception Message
外,还可以传递一些错误状态代码,以便客户端用户做进一步处理。
WebServices.cs

1. 将web服务程序设为集成windows身份验证 
 澳门新葡萄京官网注册 2

[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
   [WebMethod]
   public void TestException()
   {
     try
     {
       throw new Exception(“aaa…”);
     }
     catch (Exception e)
     {
       throw new SoapException(e.Message, new
System.Xml.XmlQualifiedName(“ErrorCode01”), e);
     }
   }
}

2.客户端web引用代码
Test.WebReference.Service1 wr = new Test.WebReference.Service1();
//生成web service实例
wr.Credentials = new NetworkCredential(“guest”,”123″);
//guest是用户名,该用户需要有一定的权限
lblTest.Text = wr.Add(2,2).ToString(); //调用web service方法
该方案的优点是比较安全,性能较好,缺点是不便于移植,部署工作量大。

Client.cs

 

WebService ws = new WebService();
try
{
   ws.TestException();
}
catch (System.Web.Services.Protocols.SoapException e)
{
   Console.WriteLine(e.Message);
   Console.WriteLine(e.Code.Name);
}

 


ASP.NET WebService
支持绝大多数的基元类型及其数组,另外还支持自定义的结构(Struct)、类型(Class)、枚举(Enum)、DataSet、XmlElement、XmlNode、集合(IEnumerable/ICollection)等。
ASP.NET WebService 使用 XmlSerializer
进行序列化操作,对于自定义类型要注意以下几点:
1.
只能序列化可读写公共属性和字段。只读属性(get;)、只读字段(readonly)、常量(const)以及所有的非
public 数据成员都不会被序列化。

  1. 自定义类型必须具有不接受任何参数的默认构造函数。
    3.
    不能序列化方法。客户端生成的代理对象不包含任何自定义类型方法(不是WebMethod)。
    基于以上几点,因此我们最好只定义纯粹用来传输复合数据的数据类型(Data
    Object)。
    以下是一些演示代码。
    基元类型

[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
public WebService () {
}
   [WebMethod]
   public DateTime GetNowTime()
   {
     return DateTime.Now;
   }
   [WebMethod]
   public string[] GetStringArray()
   {
     return new string[] { “a”, “b”, “c”};
   }
   [WebMethod]
   public float[] GetFloatArray()
   {
     return new float[]{1F, 2F, 3F};
   }
   [WebMethod]
   public byte[] GetBytes()
   {
     return System.IO.File.ReadAllBytes(@”c:windowsnotepad.exe”);
   }
}

枚举 Enum

public enum Sex
{
   Female,
   Male
}
[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
public WebService () {
}
   [WebMethod]
   public Sex GetSex()
   {
     return Sex.Female;
   }
   [WebMethod]
   public Sex[] GetAllSex()
   {
     return Enum.GetValues(typeof(Sex)) as Sex[];
   }
}

结构 Struct
结构体默认就会创建无参数构造方法,且不允许自定义。

public struct MyStruct
{
   public int X;
   public int Y;
   public MyStruct(int x, int y)
   {
     this.X = x;
     this.Y = y;
   }
}
[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
public WebService () {
}
   [WebMethod]
   public MyStruct GetMyStruct()
   {
     MyStruct st = new MyStruct(15, 16);
     return st;
   }
   [WebMethod]
   public MyStruct[] GetMyStructs()
   {
     return new MyStruct[] { new MyStruct(1, 2), new MyStruct(3, 4) };
;
   }
}

类型 Class

public struct MyStruct
{
   public int X;
   public int Y;
   public MyStruct(int x, int y)
   {
     this.X = x;
     this.Y = y;
   }
}
public class MyClass
{
   public MyClass()
   {
     myStruct = new MyStruct();
   }
   public MyClass(int x, int y, string name) : this()
   {
     myStruct.X = x;
     myStruct.Y = y;
     this.name = name;
   }
   private string name;
   public string Name
   {
     get { return name; }
     set { name = value; }
   }
   private MyStruct myStruct;
   public MyStruct MyStruct
   {
     get { return myStruct; }
     set { myStruct = value; }
   }
   public void Test() // 客户端代理不会生成该方法。
   {
     Console.WriteLine(name);
   }
}
[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
public WebService () {
}
   [WebMethod]
   public MyClass GetMyClass()
   {
     return new MyClass(1, 2, “name1”);
   }
   [WebMethod]
   public MyClass[] GetMyClassArray()
   {
     return new MyClass[] { new MyClass(1, 2, “name1”), new MyClass(2,
3, “name2”) }; ;
   }
}

有关数据类型的更详细信息,请查看 MSDN 文档。
ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_fxwebservices/html/70567d9f-6e53-42a8-bbd5-aee42b25dd28.htm


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

  1. 从目标 URL 下载 WSDL 数据。
  2. 使用 ServiceDescription 创建和格式化 WSDL 文档文件。
  3. 使用 ServiceDescriptionImporter 创建客户端代理类。
  4. 使用 CodeDom 动态创建客户端代理类程序集。
  5. 利用反射调用相关 WebService 方法。
    OK,看看具体的例子。
    我们要调用的目标 WebService,其 URL 是

    HelloWorld.asmx

[WebService(Namespace = “”,
Description=”我的Web服务”)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
public WebService () {
}
   [WebMethod]
   public string HelloWorld()
   {
     return “Hello Wolrd!”;
   }
}

1. 动态调用 WebService
客户端动态调用代码

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. 使用 WebClient 下载 WSDL 信息。
WebClient web = new WebClient();
Stream stream =
web.OpenRead(“”);
// 2. 创建和格式化 WSDL 文档。
ServiceDescription description = ServiceDescription.Read(stream);
// 3. 创建客户端代理代理类。
ServiceDescriptionImporter importer = new
ServiceDescriptionImporter();
importer.ProtocolName = “Soap”; // 指定访问协议。
importer.Style = ServiceDescriptionImportStyle.Client; //
生成客户端代理。
importer.CodeGenerationOptions =
CodeGenerationOptions.GenerateProperties |
CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null, null); // 添加 WSDL
文档。
// 4. 使用 CodeDom 编译客户端代理类。
CodeNamespace nmspace = new CodeNamespace(); //
为代理类添加命名空间,缺省为全局空间。
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. 使用 Reflection 调用 WebService。
if (!result.Errors.HasErrors)
{
   Assembly asm = result.CompiledAssembly;
   Type t = asm.GetType(“WebService”); //
如果在前面为代理类添加了命名空间,此处需要将命名空间添加到类型前面。
   object o = Activator.CreateInstance(t);
   MethodInfo method = t.GetMethod(“HelloWorld”);
   Console.WriteLine(method.Invoke(o, null));
}

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

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. 使用 WebClient 下载 WSDL 信息。
WebClient web = new WebClient();
Stream stream =
web.OpenRead(“”);
// 2. 创建和格式化 WSDL 文档。
ServiceDescription description = ServiceDescription.Read(stream);
// 3. 创建客户端代理代理类。
ServiceDescriptionImporter importer = new
ServiceDescriptionImporter();
importer.ProtocolName = “Soap”; // 指定访问协议。
importer.Style = ServiceDescriptionImportStyle.Client; //
生成客户端代理。
importer.CodeGenerationOptions =
CodeGenerationOptions.GenerateProperties |
CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null, null); // 添加 WSDL
文档。
// 4. 使用 CodeDom 编译客户端代理类。
CodeNamespace nmspace = new CodeNamespace(); //
为代理类添加命名空间,缺省为全局空间。
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”; // 可以指定你所需的任何文件名。
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)
{
   // 显示编译错误信息
}

调用程序集文件演示

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. 获取客户端代理类源代码
还有一种情形,就是我们需要获得客户端代理类的 C# 源代码。

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. 使用 WebClient 下载 WSDL 信息。
WebClient web = new WebClient();
Stream stream =
web.OpenRead(“”);
// 2. 创建和格式化 WSDL 文档。
ServiceDescription description = ServiceDescription.Read(stream);
// 3. 创建客户端代理代理类。
ServiceDescriptionImporter importer = new
ServiceDescriptionImporter();
importer.ProtocolName = “Soap”; // 指定访问协议。
importer.Style = ServiceDescriptionImportStyle.Client; //
生成客户端代理。
importer.CodeGenerationOptions =
CodeGenerationOptions.GenerateProperties |
CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null, null); // 添加 WSDL
文档。
// 4. 使用 CodeDom 编译客户端代理类。
CodeNamespace nmspace = new CodeNamespace(); //
为代理类添加命名空间,缺省为全局空间。
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace,
unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider(“CSharp”);
// 5. 保存源代码到文件。当然,你也可以直接保存到内存字符串中。
TextWriter writer = File.CreateText(“test.cs”); //
指定你所需的源代码文件名。
provider.GenerateCodeFromCompileUnit(unit, writer, null);
writer.Flush();
writer.Close();

如果你调用时触发 “WebException: 请求因 HTTP 状态 415 失败: Unsupported
Media Type。” 这样的异常,那么恭喜你和我一样郁闷
澳门新葡萄京官网注册 3,赶紧把服务器端的 WSE
关掉吧。在必须使用 WSE
的情况下,需要对客户端进行调整,至于代码需要你自己去写了。呵呵~~~~

发表评论

电子邮件地址不会被公开。 必填项已用*标注