一、前言

前面的几个章节介绍了很多理论基础,如:什么是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. tp查询范围

    一.查询范围 //说明username和password是对应模型下的  scopeUsername($query) 和scopePassword($query)方法 //关键字scope 在控制器如 ...

  2. python中如果函数后面有多于一个括号是怎么回事?

    一般而言,调用一个函数是加一个括号.如果看见括号后还有一个括号,说明第一个函数返回了一个函数,如果后面还有括号,说明前面那个也返回了一个函数.以此类推. 比如fun()() def fun(): pr ...

  3. Creating the Help Page in ASP.NET Web API

    Introduction In this article we will define the process of creating the help page in the ASP .NET We ...

  4. 网络编程之TCP/UDP及其流程比较(转)

    TCP与UDP的区别 基于连接与无连接 对系统资源的要求(TCP较多,UDP少) UDP程序结构较简单 流模式与数据报模式TCP保证数据正确性,UDP可能丢包TCP保证数据顺序,UDP不保证 具体编程 ...

  5. 在vps上安装中文环境

    现在vps默认都是安装的英文环境,其实变成中文环境也很简单.我记录以下在ubuntu下如何改变为中文环境. 1.安装中文环境包. sudo apt install language-pack-zh-h ...

  6. javascript浮点数转换成整数三种方法

    将浮点数转换成整数方法有很多,分享三种常用方法. Summary 暂时我就想到3个方法而已.如果读者想到其他好用方法,也可以交流一下 parseInt位运算符Math.floor Math.ceil ...

  7. C#操作txt文件并清空添加操作

    C#操作txt文件,进行清空添加操作的例子.代码: //把txt清空 FileStream stream = File.Open(Adr,FileMode.OpenOrCreate,FileAcces ...

  8. 【Android】10.3 网格视图(GridView)

    分类:C#.Android.VS2015: 创建日期:2016-02-19 一.简介 网格视图(GridView)是在GridLayout的基础上添加了滚动功能的视图,即:GridView用于在可滚动 ...

  9. C++ 智能指针 shared_ptr

    今天晚上去旁听了C++高级编程的课,其中提到智能指针.第一反映还以为是auto_ptr呢,一听才知道是share_ptr这个.哦,原来是C++11特性.大致的原因是auto_ptr有一点缺陷,而sha ...

  10. c++包管理工具conan

    Conan is a portable package manager, intended for C and C++ developers, but it is able to manage bui ...