一、前言

前面的几个章节介绍了很多理论基础,如:什么是WCF、WCF中的A、B、C。WCF的传输模式。本文从零开始和大家一起写一个小的WCF应用程序Demo。

大多框架的学习都是从增、删、改、查开始来学习的,我们学习WCF也是一样的。从简单来看(不包括安全、优化等相关问题),WCF的增删改查和WebForm相差无几。WCF只是把具体“实现”写在“Service端”,而“调用”放在了“Client端”。觉得有帮助别忘了点个赞哈,谢谢哦~

二、Demo说明

1)Demo的 “Service端”以本机IIS为宿主,“Client端”以WebForm项目为例。

2)Demo的“Service端”提取数据采用初学者比较容易接受的分层结构进行搭建,分别分为服务层、实体层、数据层。

引用关系如下图所示:

3)Demo以数据库为SqlServer,表User为例(sql语句在下载的压缩包中Init.sql),表结构如下所示:

字段名

列名

数据类型

约束

生成方式

用户编号

UserID

int

主键,必须输入

自动增+1

姓名

Name

varchar(200)

非必须输入

人工输入

密码

Password

varchar(200)

非必须输入

人工输入

描述

Discribe

varchar(800)

非必须输入

人工输入

提交时间

SubmitTime

datetime

非必须输入

人工输入

三、创建Service端宿主

1)创建WCF应用程序命名为:WCF.Demo.Service,如下图:

2)删除默认文件IService.cs与Service.svc。并分别创建增、删、改、查”Add.svc”、“Save.svc”、“Remove.svc”、“Get.svc,Search.svc”,分别对应4个功能的服务应用程序WCF服务应用程序,并创建数据操作层和数据实体层,如下图:

3)增加实体层和数据操作层代码,如下所示:

 1     //用户实体
2 [DataContract]
3 public class User
4 {
5 [DataMember]
6 public int UserID { get; set; }
7 [DataMember]
8 public string UserName { get; set; }
9 [DataMember]
10 public string Password { get; set; }
11 [DataMember]
12 public string Discribe { get; set; }
13 [DataMember]
14 public DateTime SubmitTime { get; set; }
15 }
16 //数据操作,调用SqlHeler
17 public class User
18 {
19 private static readonly string connectionString = "server=.;database=wcfDemo;uid=sa;pwd=123456;";
20
21 //添加
22 public static bool Add(Model.User user)
23 {
24 string sql = string.Format("INSERT INTO [dbo].[User]([UserName],[Password],[Discribe],[SubmitTime]) VALUES('{0}','{1}','{2}','{3}')", user.UserName, user.Password, user.Discribe, user.SubmitTime);
25 int result = SqlHelper.ExecuteNonQuery(connectionString, CommandType.Text, sql);
26 if (result > 0)
27 return true;
28 else
29 return false;
30 }
31
32 //修改
33 public static bool Save(Model.User user)
34 {
35 string sql = string.Format("UPDATE [dbo].[User] SET [UserName] = '{0}',[Discribe] = '{2}',[SubmitTime] = '{3}' WHERE UserID = {4}", user.UserName, user.Password, user.Discribe, user.SubmitTime, user.UserID);
36 int result = SqlHelper.ExecuteNonQuery(connectionString, CommandType.Text, sql);
37 if (result > 0)
38 return true;
39 else
40 return false;
41 }
42
43 //删除
44 public static bool Remove(int UserID)
45 {
46 string sql = string.Format("DELETE FROM [dbo].[User] WHERE UserID = {0}", UserID);
47 int result = SqlHelper.ExecuteNonQuery(connectionString, CommandType.Text, sql);
48 if (result > 0)
49 return true;
50 else
51 return false;
52 }
53
54 //获取用户
55 public static Model.User Get(int UserID)
56 {
57 Model.User user = new Model.User();
58 string sql = string.Format("SELECT * FROM [dbo].[User] WHERE UserID = {0}", UserID);
59 DataSet ds = SqlHelper.ExecuteDataset(connectionString, CommandType.Text, sql);
60 if (ds != null && ds.Tables.Count > 0)
61 {
62 foreach (DataRow dr in ds.Tables[0].Rows)
63 {
64 user.UserID = Convert.ToInt32(dr["UserID"]);
65 user.UserName = dr["UserName"].ToString();
66 user.Password = dr["Password"].ToString();
67 user.Discribe = dr["Discribe"].ToString();
68 user.SubmitTime = Convert.ToDateTime(dr["SubmitTime"]);
69 }
70 }
71 return user;
72 }
73
74 //获取用户列表
75 public static List<Model.User> GetUsers()
76 {
77 List<Model.User> Users = new List<Model.User>();
78 string sql = string.Format("SELECT * FROM [dbo].[User]");
79 DataSet ds = SqlHelper.ExecuteDataset(connectionString, CommandType.Text, sql);
80 if (ds != null && ds.Tables.Count > 0)
81 {
82 foreach (DataTable dt in ds.Tables)
83 {
84 foreach (DataRow dr in dt.Rows)
85 {
86 Model.User user = new Model.User();
87 user.UserID = Convert.ToInt32(dr["UserID"]);
88 user.UserName = dr["UserName"].ToString();
89 user.Password = dr["Password"].ToString();
90 user.Discribe = dr["Discribe"].ToString();
91 user.SubmitTime = Convert.ToDateTime(dr["SubmitTime"]);
92 Users.Add(user);
93 }
94 }
95 }
96 return Users;
97 }
98 }

4)修改Add接口的代码和实现,如下所示:

 1     [ServiceContract]
2 public interface IAdd
3 {
4 [OperationContract]
5 bool DoWork(Model.User user);
6 }
7
8 public class Add : IAdd
9 {
10 public bool DoWork(Model.User user)
11 {
12 return DAL.User.Add(user);
13 }
14 }

5)修改Save接口的代码和实现,如下所示:

 1     [ServiceContract]
2 public interface ISave
3 {
4 [OperationContract]
5 bool DoWork(Model.User user);
6 }
7
8 public class Save : ISave
9 {
10 public bool DoWork(Model.User user)
11 {
12 return DAL.User.Save(user);
13 }
14 }

6)修改Remove接口的代码和实现,如下所示:

 1     [ServiceContract]
2 public interface IRemove
3 {
4 [OperationContract]
5 bool DoWork(int UserID);
6 }
7 public class Remove : IRemove
8 {
9 public bool DoWork(int UserID)
10 {
11 return DAL.User.Remove(UserID);
12 }
13 }

7)修改Search接口的代码和实现,如下所示:

 1     [ServiceContract]
2 public interface ISearch
3 {
4 [OperationContract]
5 List<Model.User> DoWork();
6 }
7
8 public class Search : ISearch
9 {
10 List<Model.User> ISearch.DoWork()
11 {
12 return DAL.User.GetUsers();
13 }
14 }

8)修改Get接口的代码和实现,如下所示:

 1     [ServiceContract]
2 public interface IGet
3 {
4 [OperationContract]
5 Model.User DoWork(int UserID);
6 }
7
8 public class Get : IGet
9 {
10 public Model.User DoWork(int UserID)
11 {
12 return DAL.User.Get(UserID);
13 }
14 }

四、部署服务端程序

1)将程序发布,并部署到IIS上,设置端口:8080,如下图所示:

2)以Add.svc服务应用程序为目标,测试部署是否成功,成功后如下图所示:

五、创建Client端Web应用程序

新建WebForm项目WCF.Demo.Client,并创建增删改查文件,Add.aspx,Save.aspx,SearchAndRemove.aspx。如下图所示:

六、使用SvcUtil.exe生成客户端代码和配置

SvcUtil.exe是一个VS命令行工具,该工具位于:C:\Program Files\Microsoft  SDKs\Windows\v7.0A\bin 或 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\一般情况下我们将SvcUtil.exe添加到VS开发工具中方便以后的运用(也可直接使用该命令行工具)。

1)在VS中的 Tools菜单---选择External Tools,打开管理窗口如下图所示:

在Title中输入SvcUtil,Command中选择SvcUtil.exe全路径,Initial  directory栏选择生成的客户端代码和配置文件所放的目录(此处为解决方案所在目录),选上Prompt for arguments,不选上Close on  exit。点击OK.

2)添加完成后,在VS的工具下会出现这个菜单。如下图所示:

3)在Client端添加对服务的引用。打开SvUtil工具,在Arguments里填写服务的地址,如下图:

点击OK后出现下图,说明代码类和配置文件生成成功(在解决方案目标下),如下图所示:

此时代理类和配置文件被下载到解决方案的物理目录中,如下图所示:

七、在Client端使用代理类与配置

将代理类从服务端的物理目录拷贝出来,放到Client端,并适当的修改代码,加入自己需要的名称空间,如下图所示:

使用代码如下所示:

 1     //增加
2 public partial class Add : System.Web.UI.Page
3 {
4 Service.AddClient addClient = new Service.AddClient();
5 protected void Page_Load(object sender, EventArgs e)
6 {
7
8 }
9
10 //提交
11 protected void btnSubmit_Click(object sender, EventArgs e)
12 {
13 Model.User user = new Model.User();
14 user.UserName = this.txtUserName.Text;
15 user.Password = this.txtPassword.Text;
16 user.Discribe = this.txtDiscribe.Text;
17 user.SubmitTime = System.DateTime.Now;
18 addClient.DoWork(user);
19 Response.Write("添加成功!");
20 }
21 }
22 //修改
23 public partial class Save : System.Web.UI.Page
24 {
25 Service.SaveClient saveClient = new Service.SaveClient();
26 Service.GetClient getClient = new Service.GetClient();
27 protected void Page_Load(object sender, EventArgs e)
28 {
29 if (!Page.IsPostBack && !string.IsNullOrEmpty(Request.QueryString["UserID"]))
30 {
31 GetUser();
32 }
33 }
34
35 protected void GetUser()
36 {
37 int UserID = Convert.ToInt32(Request.QueryString["UserID"]);
38 Model.User user = getClient.DoWork(UserID);
39 this.txtUserName.Text = user.UserName;
40 this.txtDiscribe.Text = user.Discribe;
41 }
42
43 //提交
44 protected void btnSubmit_Click(object sender, EventArgs e)
45 {
46 int UserID = Convert.ToInt32(Request.QueryString["UserID"]);
47 Model.User user = getClient.DoWork(UserID);
48 user.UserName = this.txtUserName.Text;
49 user.Discribe = this.txtDiscribe.Text;
50 saveClient.DoWork(user);
51 Response.Write("修改成功!");
52 }
53 }
54 //列表及删除
55 public partial class SearchAndRemove : System.Web.UI.Page
56 {
57 Service.SearchClient searchClient = new Service.SearchClient();
58 Service.RemoveClient removeClient = new Service.RemoveClient();
59 protected void Page_Load(object sender, EventArgs e)
60 {
61 if (!Page.IsPostBack)
62 {
63 GetUsers();
64 }
65 }
66
67 protected void GetUsers()
68 {
69 this.repUsers.DataSource = searchClient.DoWork();
70 this.repUsers.DataBind();
71 }
72
73 protected void lbtnRemoveCommand(object sender, CommandEventArgs e)
74 {
75 int UserID = Convert.ToInt32(e.CommandName);
76 removeClient.DoWork(UserID);
77 Response.Write("删除成功~");
78 GetUsers();
79 }
80 }

将生成的配置文件中的 <system.serviceModel>复制到Client的Web.config中,代码如下:

 1   <system.serviceModel>
2 <bindings>
3 <basicHttpBinding>
4 <binding name="BasicHttpBinding_IAdd" closeTimeout="00:01:00"
5 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
6 allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
7 maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
8 messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
9 useDefaultWebProxy="true">
10 <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
11 maxBytesPerRead="4096" maxNameTableCharCount="16384" />
12 <security mode="None">
13 <transport clientCredentialType="None" proxyCredentialType="None"
14 realm="" />
15 <message clientCredentialType="UserName" algorithmSuite="Default" />
16 </security>
17 </binding>
18 <binding name="BasicHttpBinding_IRemove" closeTimeout="00:01:00"
19 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
20 allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
21 maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
22 messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
23 useDefaultWebProxy="true">
24 <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
25 maxBytesPerRead="4096" maxNameTableCharCount="16384" />
26 <security mode="None">
27 <transport clientCredentialType="None" proxyCredentialType="None"
28 realm="" />
29 <message clientCredentialType="UserName" algorithmSuite="Default" />
30 </security>
31 </binding>
32 <binding name="BasicHttpBinding_ISearch" closeTimeout="00:01:00"
33 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
34 allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
35 maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
36 messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
37 useDefaultWebProxy="true">
38 <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
39 maxBytesPerRead="4096" maxNameTableCharCount="16384" />
40 <security mode="None">
41 <transport clientCredentialType="None" proxyCredentialType="None"
42 realm="" />
43 <message clientCredentialType="UserName" algorithmSuite="Default" />
44 </security>
45 </binding>
46 <binding name="BasicHttpBinding_ISave" closeTimeout="00:01:00"
47 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
48 allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
49 maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
50 messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
51 useDefaultWebProxy="true">
52 <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
53 maxBytesPerRead="4096" maxNameTableCharCount="16384" />
54 <security mode="None">
55 <transport clientCredentialType="None" proxyCredentialType="None"
56 realm="" />
57 <message clientCredentialType="UserName" algorithmSuite="Default" />
58 </security>
59 </binding>
60 <binding name="BasicHttpBinding_IGet" closeTimeout="00:01:00"
61 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
62 allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
63 maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
64 messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
65 useDefaultWebProxy="true">
66 <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
67 maxBytesPerRead="4096" maxNameTableCharCount="16384" />
68 <security mode="None">
69 <transport clientCredentialType="None" proxyCredentialType="None"
70 realm="" />
71 <message clientCredentialType="UserName" algorithmSuite="Default" />
72 </security>
73 </binding>
74 </basicHttpBinding>
75 </bindings>
76 <client>
77 <endpoint address="http://localhost:8080/Add.svc" binding="basicHttpBinding"
78 bindingConfiguration="BasicHttpBinding_IAdd" contract="IAdd"
79 name="BasicHttpBinding_IAdd" />
80 <endpoint address="http://localhost:8080/Remove.svc" binding="basicHttpBinding"
81 bindingConfiguration="BasicHttpBinding_IRemove" contract="IRemove"
82 name="BasicHttpBinding_IRemove" />
83 <endpoint address="http://localhost:8080/Search.svc" binding="basicHttpBinding"
84 bindingConfiguration="BasicHttpBinding_ISearch" contract="ISearch"
85 name="BasicHttpBinding_ISearch" />
86 <endpoint address="http://localhost:8080/Save.svc" binding="basicHttpBinding"
87 bindingConfiguration="BasicHttpBinding_ISave" contract="ISave"
88 name="BasicHttpBinding_ISave" />
89 <endpoint address="http://localhost:8080/Get.svc" binding="basicHttpBinding"
90 bindingConfiguration="BasicHttpBinding_IGet" contract="IGet"
91 name="BasicHttpBinding_IGet" />
92 </client>
93 </system.serviceModel>

-------------------------最终效果-----------------------

添加:

修改:

列表及删除:

八、源码下载

点我下载本文章Demo

九、wcf入门教程目录

WCF入门教程一[什么是WCF]

WCF入门教程二[WCF应用的通信过程]

WCF入门教程三[WCF的宿主]

WCF入门教程四[WCF的配置文件]

WCF入门教程五[WCF的通信模式]

原文地址:http://www.cnblogs.com/iamlilinfeng/p/4083827.html

【转】WCF入门教程六[一个简单的Demo]的更多相关文章

  1. 无废话WCF入门教程六[一个简单的Demo]

    一.前言 前面的几个章节介绍了很多理论基础,如:什么是WCF.WCF中的A.B.C.WCF的传输模式.本文从零开始和大家一起写一个小的WCF应用程序Demo. 大多框架的学习都是从增.删.改.查开始来 ...

  2. WCF入门, 到创建一个简单的WCF应用程序

    什么是WCF?  WCF, 英文全称(windows Communication Foundation) , 即为windows通讯平台. windows想到这里大家都知道了 , WCF也正是由微软公 ...

  3. Express入门教程:一个简单的博客

    来自:  http://ourjs.com/detail/56b2a6f088feaf2d031d2468 Express 简介 Express 是一个简洁而灵活的 node.js Web应用框架, ...

  4. WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]

    WCF入门教程(四)通过Host代码方式来承载服务 Posted on 2014-05-15 13:03 停留的风 阅读(7681) 评论(0) 编辑 收藏 WCF入门教程(四)通过Host代码方式来 ...

  5. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  6. WCF入门教程(四)通过Host代码方式来承载服务

    WCF入门教程(四)通过Host代码方式来承载服务 之前已经讲过WCF对外发布服务的具体方式. WCF入门教程(一)简介 Host承载,可以是web,也可以是控制台程序等等.比WebService有更 ...

  7. WCF入门教程(三)定义服务协定--属性标签

    WCF入门教程(三)定义服务协定--属性标签 属性标签,成为定义协议的主要方式.先将最简单的标签进行简单介绍,以了解他们的功能以及使用规则. 服务协定标识,标识哪些接口是服务协定,哪些操作时服务协定的 ...

  8. WCF入门教程(二)如何创建WCF服务

    WCF入门教程(二)从零做起-创建WCF服务 通过最基本的操作看到最简单的WCF如何实现的.这是VS的SDK默认创建的样本 1.创建WCF服务库 2.看其生成结构 1)IService1.cs(协议) ...

  9. WCF入门教程(一)简介

    WCF入门教程(一)简介 1.WCF是什么? WCF( Windows Communication Foundation), 是Microsoft为构建面向服务的应用提供的分布式通信编程框架,是.NE ...

随机推荐

  1. Linux时间子系统(四) timekeeping

    一.前言 timekeeping模块是一个提供时间服务的基础模块.Linux内核提供各种time line,real time clock,monotonic clock.monotonic raw ...

  2. 利用eChart绘制网页图表

    首先,最好的教程在这里:eCchart eChart所需JS: echarts.min.js china.js echarts.js 页面代码如下: 一.图表 <!DOCTYPE html> ...

  3. InnoDB Master Thread I/O Rate详解

    一.innodb 在刷盘时要面对的问题: 1.对于innodb 的master thread 这个线程来说,它会在后台执行许多的任务,这些任务大多数都是与IO操作相关的, 比如“刷新脏页到磁盘”.“合 ...

  4. mysqld_safe与mysqld区别详解

    mysqld_safe与mysqld区别,直接运行mysqld程序来启动MySQL服务的方法很少见,mysqld_safe脚本会在启动MySQL服务器后继续监控其运行情况,并在其死机时重新启动它. 用 ...

  5. Android: TODO 应用交互的两种实现方法(Behavior)

    最近在写 TODO app,涉及到 Calendar 和 RecyclerView 的交互, 需求: 1. 往上滑动, Calendar 显示为周 2. 周显示模式下,往下滑动,显示为月 3. 列表下 ...

  6. [转帖]Android平台下OpenGL初步

    原文请看 Android平台下OpenGL初步 本文只关注于如何一步步实现在Android平台下运用OpenGl. 1.GLSurfaceView GLSurfaceView是Android应用程序中 ...

  7. 解决PHP下载文件时因时文件太大而报404错误

    set_time_limit(0); ini_set('memory_limit', '512M'); header('Content-Type: application/octet-stream') ...

  8. dp之分组背包hdu3033 最少取1次的解法(推荐)

    题意:有n双鞋子,m块钱,k个品牌,(一个品牌可以有多种价值不同的鞋子),接下来n种不同的鞋子,a为所属品牌,b为要花费的钱,c为所能得到的价值.每种价值的鞋子只会买一双,有个人有个伟大的梦想,每个品 ...

  9. C/C++/C#/Python日志框架

    俗话说,打得一手好log才是一个优秀的程序员. **打log的目的是为了迅速排错或在有争议时拿出证据证明自己.基于这个目的,log不在多,只要抓住一切对自己有利的信息,就可以了.** 日志框架列表 C ...

  10. JavaScript高级 面向对象(8)--浅拷贝代码实现

    说明(2017.3.31): 1. 浅拷贝,只有值属性,没有引用属性. 2. 在原对象里面添加一个copy方法,返回本对象内的所有值属性. <!DOCTYPE html> <html ...