朋友炒股两个月赚了10万,我帮他推广一下公众号,把钱用来投资总比放银行连通货膨胀都跑不过里强, 硬核离职,在家炒股 ,这是他每天的日志,有些经验是花钱也买不到的。

一、前言

前面的几个章节介绍了很多理论基础,如:什么是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 > )
  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 > )
  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 > )
  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 > )
  61. {
  62. foreach (DataRow dr in ds.Tables[].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 > )
  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="" maxBufferPoolSize="" maxReceivedMessageSize=""
  8. messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
  9. useDefaultWebProxy="true">
  10. <readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
  11. maxBytesPerRead="" maxNameTableCharCount="" />
  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="" maxBufferPoolSize="" maxReceivedMessageSize=""
  22. messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
  23. useDefaultWebProxy="true">
  24. <readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
  25. maxBytesPerRead="" maxNameTableCharCount="" />
  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="" maxBufferPoolSize="" maxReceivedMessageSize=""
  36. messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
  37. useDefaultWebProxy="true">
  38. <readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
  39. maxBytesPerRead="" maxNameTableCharCount="" />
  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="" maxBufferPoolSize="" maxReceivedMessageSize=""
  50. messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
  51. useDefaultWebProxy="true">
  52. <readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
  53. maxBytesPerRead="" maxNameTableCharCount="" />
  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="" maxBufferPoolSize="" maxReceivedMessageSize=""
  64. messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
  65. useDefaultWebProxy="true">
  66. <readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
  67. maxBytesPerRead="" maxNameTableCharCount="" />
  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

无废话WCF入门教程六[一个简单的Demo]的更多相关文章

  1. 【转】WCF入门教程六[一个简单的Demo]

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

  2. 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代码方式来 ...

  3. 无废话ExtJs 入门教程六[按钮:Button]

    无废话ExtJs 入门教程六[按钮:Button] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个按钮“提交”与重置.如下所示代码区的第68行位置, butt ...

  4. 【WCF】无废话WCF入门教程

    一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...

  5. 无废话WCF入门教程一[什么是WCF]

    http://www.cnblogs.com/iamlilinfeng/archive/2012/09/25/2700049.html wcf技术交流,同学习共进步,欢迎加群:  群号:3981831 ...

  6. 无废话WCF入门教程三[WCF的宿主]

    一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”. WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定 ...

  7. 无废话WCF入门教程二[WCF应用的通信过程]

    一.概述 WCF能够建立一个跨平台的安全.可信赖.事务性的解决方案,是一个WebService,.Net Remoting,Enterprise Service,WSE,MSMQ的并集,有一副很经典的 ...

  8. 无废话WCF入门教程五[WCF的通信模式]

    一.概述 WCF在通信过程中有三种模式:请求与答复.单向.双工通信.以下我们一一介绍. 二.请求与答复模式 描述: 客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务 ...

  9. 无废话WCF入门教程四[WCF的配置文件]

    一.概述 配置也是WCF编程中的主要组成部分.在以往的.net应用程序中,我们会把DBConn和一些动态加载类及变量写在配置文件里.但WCF有所不同.他指定向客户端公开的服务,包括服务的地址.服务用于 ...

随机推荐

  1. angularjs $broadcast 和 $on 的使用及其注意事项

    下面是demo: <div ng-controller="ParentCtrl"> www.111cn.net //父级 <div ng-controller=& ...

  2. 完整安装cocoaPods

    cocoaPods是一款xcode项目管理第三方库的工具 *ruby源码镜像下载:https://ruby.taobao.org/mirrors/ruby/*升级gem的版本: $sudo gem u ...

  3. mybatis批量插入返回主键问题

    今天整合mybatis时候用到返回主键问题,批量插入总是返回不了主键还报错. 记录入下: pom版本: <mybatis.version>3.2.6</mybatis.version ...

  4. ubuntu安装(owncloud-docker安装)

    1.源下载地址:http://mirrors.aliyun.com/ubuntu-releases/ ubuntu-16.04-server-amd64.iso 2.在虚拟机上安装完后 (1)查看IP ...

  5. ajax 无刷新上传

    最近要做微信的图文上传,因为一个图文了表中可以有多个图文,所有按钮需要随时添加,所以做了一种无刷新上传的方法. 首先我们要在html页面中写上这样的几段代码 javascript: $(functio ...

  6. Android studio Gradle 教程

    一 . Gradle基础:https://segmentfault.com/a/1190000002439306 module下的gradle文件: // 声明是Android程序 apply plu ...

  7. SQL-Server使用点滴(二)

    二,对象的建立和使用 1,了解MSSql的[系统表] 对于SQL-Server中的所有对象,包括数据库,数据表,记录,字段,触发器,索引,数据类型等元素,均有对应的系统表记性记录.系统表是禁止直接删改 ...

  8. BW知识问答锦集2

    PM面试分为BW.BO两部分,根据顾问的简历和应聘的岗位所侧重的问题不同. BW包括基础知识.增量.增强.LO抽取.数据源. BO包括 CR.CR.WEBI.UNI. 一. 基础知识 技术面试 1. ...

  9. IOS 微信 6.5.2 自动播放音乐 解决方案

    之前仅仅是IPhone7\7p 的问题,现在已经扩展到6 .6s.今天在下也行了最新微信,音乐问题果然来了. 好了 下面直接进入正题 首先 引入 <script src="http:/ ...

  10. 不完全解决Android微信HTML5 播放视频的问题(不显示控制条,可交互)

    首先你需要知道以下内容: http://ad.weixin.qq.com/learn/2-3-3--%E9%80%9A%E7%94%A8%E5%BA%93 这是微信为广告商开放的API,我一直认为只有 ...