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

在 .NET Compact Framework 中使用 WCF

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (13投票s)

2009年6月14日

CPOL

3分钟阅读

viewsIcon

91437

downloadIcon

3458

本文将向您展示如何从 PDA 设备创建 WCF Web 服务的代理客户端。

screen1.jpg

引言

创建各种 Web 服务时,我们可以非常轻松地以各种方式为 PC 创建客户端代理:可以通过 Visual Studio 中的“添加服务引用”工具,或者简单地通过命令行svcutil.exe设置参数,最后得到代码和配置文件。但是,如果我们业务涉及 Pocket PC 或 Smartphone 等便携式设备怎么办?幸运的是,这个问题有解决方案,我将在本文中进行介绍。

问题的解决方案

例如,我们将在 Visual Studio 2008 中创建新的 WCF Web 服务 - **文件 -> 新建 -> 项目 -> Web -> WCF 服务应用程序**,命名为BooksService。然后,在创建了必要的数据类型和函数后,我们启动 Web 服务。它可能在 IIS 6.0/7.0 或 VS2008 内置的 ASP.NET 开发服务器中运行。那么,现在可以提出一个公平的问题——我们如何从掌上电脑连接到我们的服务?幸运的是,无需编写自己的代理类,有一种更简单的方法,那就是使用实用程序netcfsvcutil.exe,您可以从此链接下载。然后,我们在给定实用程序的参数中设置下一行:“http://192.168.134.10:8888/BooksService.svc”。退出后,我们将获得两个文件:CFClientBase.csBooksServie.cs。这正是我们需要的。现在,我将详细介绍服务创建及其便捷的移动客户端的创建。

WCF 服务

创建此 Web 服务后,我们将其接口声明如下:

[ServiceContract]
    public interface IBooksService
    {
        [OperationContract]
        string[] GetBookNames();
        [OperationContract]
        Book[] GetBooks(GetBookType type, string input);
        [OperationContract]
        Book[] GetAllBooks();
        // TODO: Add your service operations here
    }

正如您所见,代码中使用的类是Book。其实现如下:

[DataContract]
    public class Book
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Author { get; set; }
        [DataMember]
        public string ISBN { get; set; }
        [DataMember]
        public decimal Price { get; set; }
        [DataMember]
        public string Description { get; set; }
    }

    public enum GetBookType
    {
        ISBN, Name, Author
    }

但是服务在哪里获取这些关于书籍的信息呢?为了不使示例复杂化,我们将在App_Data文件夹中内置一个 XML 文件data.xml来存储我们的数据,而不是处理 SqlServer 或 Oracle 等数据库。

<Books>
  <Book>
    <Name>Data Access and Web Services for Rich Internet Applications</Name>
    <Author>John Papa</Author>
    <ISBN>0-596-52309-2</ISBN>
    <Price>44,99</Price>
    <Description>This comprehensive bookl teaches you how to build
	data-rich business applications with Silverlight 2 that draw on
	multiple sources of data. Packed with reusable examples,
	Data-Driven Services with Silverlight 2 covers all of the data access
	and web service tools you need, including data binding, the LINQ
	data querying component, RESTful and SOAP web service support,
	cross-domain web service calls, and Microsoft's new ADO.NET Data Services
	and the ADO.NET Entity Framework.</Description>
  </Book>
...
<Books>

IBooksService接口的实现如下:

public class BooksService : IBooksService
    {
        XDocument document = XDocument.Load(String.Format("{0}\\{1}\\{2}",
	HostingEnvironment.ApplicationPhysicalPath, "App_Data",
	"data.xml")); //getting path to the web service location and data file

        public string[] GetBookNames()
        {
            var q = from dest in document.Root.Elements("Book")
                    select dest.Element("Name").Value; //return only name
            return q.ToArray();
        }

        public Book[] GetBooks(GetBookType type, string input)
        {
            switch (type)
            {
                case GetBookType.ISBN: //if user select "ISBN" filter
                    {
                        var q = from dest in document.Root.Elements("Book")
                                where dest.Element("ISBN").Value ==
				input //Strict comparison of the "ISBN" data
                                select new Book()
                                {
                                    Author = dest.Element("Author").Value,
                                    Description = dest.Element("Description").Value,
                                    ISBN = dest.Element("ISBN").Value,
                                    Name = dest.Element("Name").Value,
                                    Price = Convert.ToDecimal(dest.Element("Price").Value)
                                };
                        return q.ToArray();
                    }
                case GetBookType.Author: //if user select "Author" filter
                    {
                        var q = from dest in document.Root.Elements("Book")
                                where dest.Element("Author").Value.ToLower().
				IndexOf(input.ToLower()) != -1 //Change of the
					//register on lower and search of
					//occurrence of a line "input"
					//in an initial line
                                select new Book()
                                {
                                    Author = dest.Element("Author").Value,
                                    Description = dest.Element("Description").Value,
                                    ISBN = dest.Element("ISBN").Value,
                                    Name = dest.Element("Name").Value,
                                    Price = Convert.ToDecimal(dest.Element("Price").Value)
                                };
                        return q.ToArray();
                    }
                case GetBookType.Name: //if user select "Author" filter
                    {
                        var q = from dest in document.Root.Elements("Book")
                                where dest.Element("Name").Value.ToLower().
				IndexOf(input.ToLower()) != -1 //Change of the
				//register on lower and search of
				//occurrence of a line "input" in an initial line
                                select new Book()
                                {
                                    Author = dest.Element("Author").Value,
                                    Description = dest.Element("Description").Value,
                                    ISBN = dest.Element("ISBN").Value,
                                    Name = dest.Element("Name").Value,
                                    Price = Convert.ToDecimal(dest.Element("Price").Value)
                                };
                        return q.ToArray();
                    }
                default:
                    {
                        return new List().ToArray();
                    }
            }
        }

        public Book[] GetAllBooks()
        {
            var q = from dest in document.Root.Elements("Book") //return all books
                    select new Book()
                    {
                        Author = dest.Element("Author").Value,
                        Description = dest.Element("Description").Value,
                        ISBN = dest.Element("ISBN").Value,
                        Name = dest.Element("Name").Value,
                        Price = Convert.ToDecimal(dest.Element("Price").Value)
                    };
            return q.ToArray();
        }
    }

您可以看到,我使用 LINQ to XML 处理 XML 数据,因为这对我来说是最简单的方法。现在,我们有了现成的服务,可以将其部署到任何托管上并连接到指定地址。因此,我们将开始最有趣的部分——为其创建掌上客户端。

PDA 客户端

首先,您应该创建一个新的**智能设备项目**。之后,您将获得一个新的空窗体及其自动创建的初始化代码。目前可以暂停。正如我在“问题解决方案”部分所说,您应该运行netcfsvcutil.exe并使用所需的参数启动。您应该将CFClientBase.csBooksService.cs文件添加到当前项目中。现在您已经拥有了现成的代理类。让我们看看如何正确初始化与我们服务的连接。

private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                string remoteAddress = HelpClass.BuildUrl(); //get address
                EndpointAddress endpoint = new EndpointAddress(remoteAddress);
                client = new BooksServiceClient(new BasicHttpBinding(),
				endpoint); //create new client proxy
                comboBox1.Items.Clear();
                foreach (string s in client.GetBookNames())
                {
                    comboBox1.Items.Add(s);
                }
                books.Clear();
                books.AddRange(client.GetAllBooks()); //get all names of the books
                seed = 0;
                if (books.Count > 1)
                    button1.Enabled = true;
                comboBox1.SelectedIndex = 0;
            }
            catch (Exception ex) { MessageBox.Show(string.Format
				("Connection Error: {0}", ex.Message)); }
        }

已使用HelpClass

public static class HelpClass
    {
        static XDocument doc = XDocument.Load
	(Assembly.GetExecutingAssembly().GetName().CodeBase.Substring(0,
	Assembly.GetExecutingAssembly().GetName().CodeBase.LastIndexOf('\\') + 1) +
	"settings.xml");

        public static string BuildUrl()
        {
            return string.Format("http:/ /a{0}:{1}/BooksService.svc",
		doc.Root.Element("Host").Value, doc.Root.Element("Port").Value);
        }
    }

因此,在连接到终结点后,您可以全面使用 Web 服务提供的所有功能。

结论

总而言之,正如您所看到的,创建服务的简单客户端并不需要特殊的技巧。所有代理创建的基本工作都由实用程序netcfsvcutil.exe承担,您的责任是提供服务地址并使用basicHttp绑定初始化客户端。祝您好运!

screen.JPG

历史

  • 2009 年 6 月 14 日:初次发布
© . All rights reserved.