Web服务与二进制传输
2002-11-26 14:15
Web服务与二进制传输
王凌峰
本文将要讨论 XML 二进制对象的序列化。在这个例子中,我们构造的 Web
服务将以二进制数组的形式输出一张图片,它也可以是 mp3、应用程序或者任何其它二进制信息。
可能的用途包括 Web
服务发布最新的新闻照片、gif 格式的统计图表等。这些图片当然可以直接发布在 Web 应用程序的企业层上,但是如果公司仅仅需要向位于 Internet
上的图片供应商发出请求就能得到它们,岂不更好?
- “嗨,我是 cshrp.net 上的一个网页。我想得到这些数据的饼状图和相关信息。快。”
- “哦,网页你好。没问题,图片很快就到,正在进行 HTTP 传输,请稍候。”
-
“哇,酷。请问能否在一小时后根据新的数据绘出饼状图再传给我?”
- “呵呵,好说,好说。我是 web 服务,没有做不到的。”
对,就这样。明白了?好,来看看下列代码,我们将用它来传送一张示范图片
C:\Inetpub\wwwroot\webservices\Sample.jpg 。
<%@ WebService
Language="C#" Class="Binaries"%>
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using
System.Web.Services;
public class Binaries : WebService
{
[WebMethod()]
public Byte[] GetBinary()
{
Image sample = new
Bitmap(@"C:\Inetpub\wwwroot\webservices\Sample.jpg");
MemoryStream output =
new MemoryStream();
sample.Save(output, ImageFormat.Jpeg);
return output.GetBuffer();
}
}
既然我们要处理的是图片,当然要包含名字空间 System.DrawingandSystem.Imaging 。我们要建立的是一个
Web 服务,并且用到了 MemoryStream 对象,因此还要包含 System.IOandSystem.Web.Service 。
代码十分简单。然后,我们创建了包含那张图片的 image 对象。接下来,我们创建 MemoryStream 以容纳图片,并且以
MemoryStream 和文件格式作为参数调用 image 对象的 Save 方法。
Web
服务一旦投入运行,就能等待客户端了。在本例中,客户端是一个 windows 应用程序。但它也可以是能与 Web 服务交互的 html、wml、xml等等。
我们使用一个代理服务类让系统将 Web 服务看成本地类。代理服务类可以看成介于本地应用程序和 Web 服务之间的通道。它能将你的要求翻译成
Web 服务器的语言。
有一个小巧玲珑的公用程序 wsdl.exe 可以充当代理服务类。顺便提一句,WSDL 是 Web
服务描述语言的缩写,它是一种用于描述 Web 服务的 XML 格式,可以让人们知道代理服务类都做些什么。通过把 WSDL 作为 web
服务的查询字串就能得到它的 wsdl 描述:
myWebService.asmx?WSDL
这个 url
可以作为参数传递给 wsdl.exe:
wsdl http://local/myservice.asmx?WSDL
我们根据 Web 服务类命名 C# 代码文件。比如上面那段代码的文件名就是 Binaries.cs 。现在把它编译成一个
module :
csc/t:module Binaries.cs
然后把下列源代码文件和 .NET
模组文件放在同一目录下:
using System;
using System.Drawing;
using
System.Collections;
using System.ComponentModel;
using
System.Windows.Forms;
using System.IO;
public class
BinaryConsumer : Form
{
Button btnLoad;
PictureBox pbxBinaryImage;
Binaries myService;
public BinaryConsumer()
{
myService = new Binaries();
this.btnLoad = new Button();
this.pbxBinaryImage = new PictureBox();
this.btnLoad.Location
= new Point(176, 240);
this.btnLoad.Name = "btnLoad";
this.btnLoad.Text
= "Load Image";
this.btnLoad.Click += new EventHandler(this.btnLoad_Click);
this.pbxBinaryImage.Location = new Point(24, 8);
this.pbxBinaryImage.Name = "pbxBinaryImage";
this.pbxBinaryImage.Size =
new Size(232, 224);
this.pbxBinaryImage.TabStop = false;
this.AutoScaleBaseSize = new Size(5, 13);
this.ClientSize =
new Size(292, 273);
this.Controls.AddRange(new Control[] {
this.btnLoad,
this.pbxBinaryImage});
this.Name = "BinaryConsumer";
this.Text =
"BinaryConsumer";
}
static void Main()
{
Application.Run(new BinaryConsumer());
}
private void
btnLoad_Click(object sender, System.EventArgs e)
{
byte[] image =
myService.GetBinary();
MemoryStream memStream = new
MemoryStream(image);
Bitmap bm = new Bitmap(memStream);
pbxBinaryImage.Visible = false;
pbxBinaryImage.Image = bm;
pbxBinaryImage.Visible = true;
}
}
这就是我们的客户端。大部份代码都是用户接口,不管它,直接看这一段:
private void
btnLoad_Click(object sender, System.EventArgs e)
{
byte[] image =
myService.GetBinary();
MemoryStream memStream = new
MemoryStream(image);
Bitmap bm = new Bitmap(memStream);
pbxBinaryImage.Visible = false;
pbxBinaryImage.Image = bm;
pbxBinaryImage.Visible = true;
}
这段代码用于输出图片。它被关联到了按钮
btnLoad 上。单击此按钮,Web 服务就会把请求的图片传过来。注意,我们在一开始就创建了一个 Binaries 对象 myService
。再有,是否还记得,我们的 Web 服务包含一个 GetBinary 方法 ,作用是返回图片的确切字节数。客户端和 Web 服务之间的各种调用和数据经过
SOAP 序列化,以 HTTP 方式来回传递。整个过程就是这样。
注意:代码可以从 http://www.cshrp.net/content/code/binaries.zip
下载到。经过编译的代理服务类在 beta 2 下运行通过,但是在 Final 版则不行,除非使用新的代理服务类 wsdl.exe
。好了,祝一切顺利。