65.9K
CodeProject 正在变化。 阅读更多。
Home

Web 服务介绍:每日 Dilbert

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.64/5 (61投票s)

2003 年 4 月 13 日

6分钟阅读

viewsIcon

285579

downloadIcon

2821

通过创建用于检索每日 Dilbert 图片的 Web 服务以及一个用于消费此服务的客户端来入门 Web 服务。

引言

Web 服务是一项非常强大的技术,极大地推动了分布式计算的思想。Web 服务不为追求更好技术而创建或重新发明协议,而是利用 XML、HTTP 和 SSL 等强大、可靠的技术。

与 Microsoft SOAP Toolkit 时代相比,Web 服务创建已得到极大改进。Web 服务架构已集成到 .NET Framework 中,只需单击几下即可获得一个可用的 Web 服务。

在本文中,我计划使用 Microsoft .NET Framework 和 Visual Studio .NET 为您提供创建 Web 服务的基础介绍。我将引导您完成创建检索每日 Dilbert 图片的 Web 服务以及一个消费该服务的客户端。

本文假定您对 C# 语言有基本的了解,并且熟悉 Visual Studio .NET IDE。

我们开始吧...

我们将创建一个名为 DailyDilbert 的新的 ASP.NET Web 服务项目。创建项目后,您将在解决方案资源管理器中看到几个项目文件。Web 服务本身位于 Service1.asmx。为了更清楚起见,我们的第一步是将此文件重命名为更合适的内容。我们称之为 DilbertService.asmx

要从我们的类创建 Web 服务,我们需要将我们的类派生自 System.Web.Services.WebService。使用属性,我们将描述我们的 Web 服务类,为其提供命名空间和描述。MSDN 库将 XML 命名空间定义为“一种在 XML 文档中创建由统一资源标识符 (URI) 标识的名称的方式。通过使用 XML 命名空间,您可以唯一地标识 XML 文档中的元素或属性。XML Web 服务的服务描述在 XML 中定义,特别是 Web 服务描述语言 (WSDL) 中。”命名空间是任意的,不需要指向 Internet 站点。

代码应如下所示

[WebService(
    Description="Provides methods to access the daily Dilbert image",
    Namespace="http://mattberther.com/webservices/dailydilbert")]

我们的 Web 服务将利用 System.NetSystem.IOSystem.Text.RegularExpressions 命名空间中的函数,因此让我们在 DilbertService.asmx.cs 文件顶部添加以下行

using System.Net;
using System.IO;
using System.Text.RegularExpression;

现在我们的类声明已就绪,让我们继续进行有趣的部分。将以下方法添加到您的 DilbertService 类中

public string GetDailyDilbertUrl()
{
    string address = "http://www.dilbert.com/comics/dilbert/archive/";

    WebClient httpRequest = new WebClient();
    StreamReader rdr = new StreamReader(httpRequest.OpenRead(address),
        System.Text.Encoding.ASCII);
    string streamText = rdr.ReadToEnd();
    rdr.Close();

    Match match = Regex.Match(streamText,
        @"/comics/dilbert/archive/images/(\w+).gif",
        RegexOptions.IgnoreCase);

    if (match != Match.Empty)
    {
        return "http://www.dilbert.com" + match.Value;
    }
    else
    {
        return "";
    }
}

此方法非常直接。我们打开对每日 Dilbert 页面的 Web 请求,并检索 HTML 页面的 string。当您从 http://www.dilbert.com/comics/dilbert/archive/ 执行“查看源”时,我们会看到显示的图片位于 /comics/dilbert/archive/images。正则表达式匹配该模式,并向上取一个单词字符,直到遇到 .gif。如果正则表达式解析器找到匹配项,则该匹配项的值将附加到基本 URL 并返回给客户端。

因此,我们现在有一个检索每日 Dilbert 图片 URL 的方法。但是,当我们运行 Web 服务(通过 F5)时,我们发现 Web 服务上没有可用的操作。要使我们的方法可以被远程 Web 客户端调用,我们需要将 WebMethod 属性应用于我们的方法。在方法声明的正上方添加以下行

[WebMethod(
    Description="Retrieve the URL for the daily Dilbert image")]

现在,当我们运行 Web 服务时,通过单击 Internet Explorer 中的链接,我们会发现我们的方法是可用的。当您单击此链接时,会出现一个自动生成的页面,其中显示有关我们方法的信息。此信息包括通过 SOAP 和 HTTP POST 访问此服务的语法信息。您还可以通过“调用”按钮测试您的 Web 服务。

让我们向 Web 服务添加另一个方法,它将返回图片本身的字节数组。将以下代码添加到 DilbertService 类中

[WebMethod(
    Description="Retrieve a byte array containing the daily Dilbert image")]
public byte[] GetDailyDilbertImage()
{
    WebClient httpRequest = new WebClient();
    String imageUrl = GetDailyDilbertUrl();

    BinaryReader rdr = new BinaryReader(
        httpRequest.OpenRead(imageUrl));

    byte[] imageArray = ConvertStreamToByteArray(rdr.BaseStream);
    rdr.Close();

    return imageArray;
}

private byte[] ConvertStreamToByteArray(Stream theStream)
{
    int b1;
    MemoryStream tempStream = new MemoryStream();
    while( (b1 = theStream.ReadByte()) != -1)
    {
        tempStream.WriteByte(((byte)b1));
    }

    return tempStream.ToArray();
}

同样,这是一个非常直接的方法。我们使用先前创建的方法检索图片 URL,然后创建一个 BinaryReader 来读取 .gif 文件。我们添加了一个简单的帮助方法来将 Stream 对象转换为字节数组。

现在,当我们运行项目时,我们会发现此附加方法也可用。当我们单击新方法并进行测试时,我们会收到一个包含图片数据的 base64encoded string

如果没人消费我们的 Web 服务,它就没什么用。因此,让我们创建一个简单的 WinForms 应用程序来消费我们新的 Web 服务。

向您的解决方案添加一个名为 DilbertServiceClient 的新 Windows 应用程序。要引用 Web 服务,我们需要添加一个 Web 引用。右键单击 DilbertServiceClient 项目,然后选择“添加 Web 引用”。在 URL 框中键入 https:///DailyDilbert/DilbertService.asmx,然后单击“转到”。同样,您将看到与通过 Visual Studio(通过 F5)执行 Web 服务时看到的页面相同的页面。将 Web 引用名称更新为您想要的命名空间。在本文中,我将使用 MattBerther.DailyDilbert。现在,消费此 Web 服务就像创建一个实例并调用相应的方法一样简单,如下面的 Form1.cs 中的代码所示。

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    MattBerther.DailyDilbert.DilbertService ws =
        new MattBerther.DailyDilbert.DilbertService();

    Byte[] imageData = ws.GetDailyDilbertImage();
    System.IO.MemoryStream strm = new System.IO.MemoryStream(imageData);
    Bitmap bmp = new Bitmap(strm);
    strm.Close();

    PictureBox box = new PictureBox();
    box.Image = bmp;
    box.Height = bmp.Height;
    box.Width = bmp.Width;

    this.Controls.Add(box);
    this.Height = bmp.Height;
    this.Width = bmp.Width;

    this.Text = "Daily Dilbert Image: " + ws.GetDailyDilbertUrl();
}

现在我们已经创建了 Web 服务和消费它的客户端,让我们看看一些增强此服务的方法。首先,您可能会意识到这些方法的输出每天只更改一次。与其在每次请求时都解析每日 Dilbert 页面,不如缓存请求更有意义。缓存 Web 方法结果非常直接。只需将 CacheDuration 属性添加到 WebMethod 属性,如下所示

[WebMethod(
    Description="Retrieve the URL for the daily Dilbert image",
    CacheDuration=43200)]

CacheDuration 获取或设置响应应在缓存中保留的秒数。为尽量减少对主 Dilbert 页面的请求次数,我们将响应缓存设置为 12 小时(43200 秒)。我们可以通过在 Web 方法的第一行设置断点,然后连续运行客户端来验证缓存是否正常工作。客户端将获得缓存的响应,直到

  1. 缓存超时已过期,或
  2. IIS 已重置

当我们考虑将 Dilbert 应用程序部署到其他桌面时,我们可能希望提供一些功能来更改 Web 服务指向的 URL。使用 Visual Studio .NET 和 .NET Framework,这就像将 Web 引用的 URLBehavior 属性从静态更改为动态一样简单。当您更改为动态时,将在 app.config 文件中添加一个名为 DilbertServiceClient.MattBerther.DailyDilbert.DilbertService 的键。此键的值是要用于消费 Web 服务的 URL。

历史

  • 1.0 - 04.13.2003
    • 首个发布版本

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.