无废话WCF入门教程六[一个简单的Demo]
朋友炒股两个月赚了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)增加实体层和数据操作层代码,如下所示:
//用户实体
[DataContract]
public class User
{
[DataMember]
public int UserID { get; set; }
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Password { get; set; }
[DataMember]
public string Discribe { get; set; }
[DataMember]
public DateTime SubmitTime { get; set; }
}
//数据操作,调用SqlHeler
public class User
{
private static readonly string connectionString = "server=.;database=wcfDemo;uid=sa;pwd=123456;"; //添加
public static bool Add(Model.User user)
{
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);
int result = SqlHelper.ExecuteNonQuery(connectionString, CommandType.Text, sql);
if (result > )
return true;
else
return false;
} //修改
public static bool Save(Model.User user)
{
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);
int result = SqlHelper.ExecuteNonQuery(connectionString, CommandType.Text, sql);
if (result > )
return true;
else
return false;
} //删除
public static bool Remove(int UserID)
{
string sql = string.Format("DELETE FROM [dbo].[User] WHERE UserID = {0}", UserID);
int result = SqlHelper.ExecuteNonQuery(connectionString, CommandType.Text, sql);
if (result > )
return true;
else
return false;
} //获取用户
public static Model.User Get(int UserID)
{
Model.User user = new Model.User();
string sql = string.Format("SELECT * FROM [dbo].[User] WHERE UserID = {0}", UserID);
DataSet ds = SqlHelper.ExecuteDataset(connectionString, CommandType.Text, sql);
if (ds != null && ds.Tables.Count > )
{
foreach (DataRow dr in ds.Tables[].Rows)
{
user.UserID = Convert.ToInt32(dr["UserID"]);
user.UserName = dr["UserName"].ToString();
user.Password = dr["Password"].ToString();
user.Discribe = dr["Discribe"].ToString();
user.SubmitTime = Convert.ToDateTime(dr["SubmitTime"]);
}
}
return user;
} //获取用户列表
public static List<Model.User> GetUsers()
{
List<Model.User> Users = new List<Model.User>();
string sql = string.Format("SELECT * FROM [dbo].[User]");
DataSet ds = SqlHelper.ExecuteDataset(connectionString, CommandType.Text, sql);
if (ds != null && ds.Tables.Count > )
{
foreach (DataTable dt in ds.Tables)
{
foreach (DataRow dr in dt.Rows)
{
Model.User user = new Model.User();
user.UserID = Convert.ToInt32(dr["UserID"]);
user.UserName = dr["UserName"].ToString();
user.Password = dr["Password"].ToString();
user.Discribe = dr["Discribe"].ToString();
user.SubmitTime = Convert.ToDateTime(dr["SubmitTime"]);
Users.Add(user);
}
}
}
return Users;
}
}
4)修改Add接口的代码和实现,如下所示:
[ServiceContract]
public interface IAdd
{
[OperationContract]
bool DoWork(Model.User user);
} public class Add : IAdd
{
public bool DoWork(Model.User user)
{
return DAL.User.Add(user);
}
}
5)修改Save接口的代码和实现,如下所示:
[ServiceContract]
public interface ISave
{
[OperationContract]
bool DoWork(Model.User user);
} public class Save : ISave
{
public bool DoWork(Model.User user)
{
return DAL.User.Save(user);
}
}
6)修改Remove接口的代码和实现,如下所示:
[ServiceContract]
public interface IRemove
{
[OperationContract]
bool DoWork(int UserID);
}
public class Remove : IRemove
{
public bool DoWork(int UserID)
{
return DAL.User.Remove(UserID);
}
}
7)修改Search接口的代码和实现,如下所示:
[ServiceContract]
public interface ISearch
{
[OperationContract]
List<Model.User> DoWork();
} public class Search : ISearch
{
List<Model.User> ISearch.DoWork()
{
return DAL.User.GetUsers();
}
}
8)修改Get接口的代码和实现,如下所示:
[ServiceContract]
public interface IGet
{
[OperationContract]
Model.User DoWork(int UserID);
} public class Get : IGet
{
public Model.User DoWork(int UserID)
{
return DAL.User.Get(UserID);
}
}
四、部署服务端程序
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端,并适当的修改代码,加入自己需要的名称空间,如下图所示:
使用代码如下所示:
//增加
public partial class Add : System.Web.UI.Page
{
Service.AddClient addClient = new Service.AddClient();
protected void Page_Load(object sender, EventArgs e)
{ } //提交
protected void btnSubmit_Click(object sender, EventArgs e)
{
Model.User user = new Model.User();
user.UserName = this.txtUserName.Text;
user.Password = this.txtPassword.Text;
user.Discribe = this.txtDiscribe.Text;
user.SubmitTime = System.DateTime.Now;
addClient.DoWork(user);
Response.Write("添加成功!");
}
}
//修改
public partial class Save : System.Web.UI.Page
{
Service.SaveClient saveClient = new Service.SaveClient();
Service.GetClient getClient = new Service.GetClient();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack && !string.IsNullOrEmpty(Request.QueryString["UserID"]))
{
GetUser();
}
} protected void GetUser()
{
int UserID = Convert.ToInt32(Request.QueryString["UserID"]);
Model.User user = getClient.DoWork(UserID);
this.txtUserName.Text = user.UserName;
this.txtDiscribe.Text = user.Discribe;
} //提交
protected void btnSubmit_Click(object sender, EventArgs e)
{
int UserID = Convert.ToInt32(Request.QueryString["UserID"]);
Model.User user = getClient.DoWork(UserID);
user.UserName = this.txtUserName.Text;
user.Discribe = this.txtDiscribe.Text;
saveClient.DoWork(user);
Response.Write("修改成功!");
}
}
//列表及删除
public partial class SearchAndRemove : System.Web.UI.Page
{
Service.SearchClient searchClient = new Service.SearchClient();
Service.RemoveClient removeClient = new Service.RemoveClient();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GetUsers();
}
} protected void GetUsers()
{
this.repUsers.DataSource = searchClient.DoWork();
this.repUsers.DataBind();
} protected void lbtnRemoveCommand(object sender, CommandEventArgs e)
{
int UserID = Convert.ToInt32(e.CommandName);
removeClient.DoWork(UserID);
Response.Write("删除成功~");
GetUsers();
}
}
将生成的配置文件中的 <system.serviceModel>复制到Client的Web.config中,代码如下:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IAdd" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="" maxBufferPoolSize="" maxReceivedMessageSize=""
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
maxBytesPerRead="" maxNameTableCharCount="" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
<binding name="BasicHttpBinding_IRemove" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="" maxBufferPoolSize="" maxReceivedMessageSize=""
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
maxBytesPerRead="" maxNameTableCharCount="" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
<binding name="BasicHttpBinding_ISearch" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="" maxBufferPoolSize="" maxReceivedMessageSize=""
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
maxBytesPerRead="" maxNameTableCharCount="" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
<binding name="BasicHttpBinding_ISave" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="" maxBufferPoolSize="" maxReceivedMessageSize=""
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
maxBytesPerRead="" maxNameTableCharCount="" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
<binding name="BasicHttpBinding_IGet" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="" maxBufferPoolSize="" maxReceivedMessageSize=""
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength=""
maxBytesPerRead="" maxNameTableCharCount="" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8080/Add.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IAdd" contract="IAdd"
name="BasicHttpBinding_IAdd" />
<endpoint address="http://localhost:8080/Remove.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IRemove" contract="IRemove"
name="BasicHttpBinding_IRemove" />
<endpoint address="http://localhost:8080/Search.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ISearch" contract="ISearch"
name="BasicHttpBinding_ISearch" />
<endpoint address="http://localhost:8080/Save.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ISave" contract="ISave"
name="BasicHttpBinding_ISave" />
<endpoint address="http://localhost:8080/Get.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IGet" contract="IGet"
name="BasicHttpBinding_IGet" />
</client>
</system.serviceModel>
-------------------------最终效果-----------------------
添加:
修改:
列表及删除:
八、源码下载
九、wcf入门教程目录
版权:http://www.cnblogs.com/iamlilinfeng
无废话WCF入门教程六[一个简单的Demo]的更多相关文章
- 【转】WCF入门教程六[一个简单的Demo]
一.前言 前面的几个章节介绍了很多理论基础,如:什么是WCF.WCF中的A.B.C.WCF的传输模式.本文从零开始和大家一起写一个小的WCF应用程序Demo. 大多框架的学习都是从增.删.改.查开始来 ...
- 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代码方式来 ...
- 无废话ExtJs 入门教程六[按钮:Button]
无废话ExtJs 入门教程六[按钮:Button] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个按钮“提交”与重置.如下所示代码区的第68行位置, butt ...
- 【WCF】无废话WCF入门教程
一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...
- 无废话WCF入门教程一[什么是WCF]
http://www.cnblogs.com/iamlilinfeng/archive/2012/09/25/2700049.html wcf技术交流,同学习共进步,欢迎加群: 群号:3981831 ...
- 无废话WCF入门教程三[WCF的宿主]
一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”. WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定 ...
- 无废话WCF入门教程二[WCF应用的通信过程]
一.概述 WCF能够建立一个跨平台的安全.可信赖.事务性的解决方案,是一个WebService,.Net Remoting,Enterprise Service,WSE,MSMQ的并集,有一副很经典的 ...
- 无废话WCF入门教程五[WCF的通信模式]
一.概述 WCF在通信过程中有三种模式:请求与答复.单向.双工通信.以下我们一一介绍. 二.请求与答复模式 描述: 客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务 ...
- 无废话WCF入门教程四[WCF的配置文件]
一.概述 配置也是WCF编程中的主要组成部分.在以往的.net应用程序中,我们会把DBConn和一些动态加载类及变量写在配置文件里.但WCF有所不同.他指定向客户端公开的服务,包括服务的地址.服务用于 ...
随机推荐
- TRUNCATE TABLE (Transact-SQL)
删除表中的所有行,而不记录单个行删除操作. TRUNCATE TABLE 与没有 WHERE 子句的 DELETE 语句类似:但是,TRUNCATE TABLE 速度更快,使用的系统资源和事务日志资源 ...
- jira 6.3.6安装-汉化-破解
jira是是一个国外的项目管理软件,收费的,至于功能什么的这里就不具体说了,大家可以网上查看有很多描述的 首先你要在JIRA官网注册一个账户,可以有30天的试用期,网上很多教程是让你去网上搜一个密钥, ...
- NSValue 类的使用
NSValue对象是用来存储一个C或者Objective-C数据的简单容器.它可以保存任意类型的数据int,float,char等,也可以是指pointers, structures, and obj ...
- python 最大公约数
求解两个整数(不能是负数)的最大公约数(要求两数不能同时为0)当两数都是0时,最大公约数为0方式一:穷举法 def GCU(m, n): if not m: return n elif not n: ...
- [Python]实现简单决策树
基本思路: 通过香农熵来决定每一层使用哪一种标签做分类,分类后,通过多数表决法来决定该层两个节点的类别.每次消耗一个标签,所以一共需要递归"标签个数"层. # -*- coding ...
- mac上的git环境配置
git生成ssh key for mac 打开终端 cd ~/.ssh 看有没有文件 没有的时候 有有ssh key是这样的多了id_rsa(私钥)和 id_rsa.pub(公钥) 没有的话创建 ss ...
- 图像预处理第9步:存为.bmp文件
//图像预处理第9步:将最终标准化后的字符图像分为单个单个的HDIB保存,并存为.bmp文件 void CChildView::OnImgprcToDibAndSave() { unsigned ch ...
- Javascript 数组常用操作方法
一.数组 Array 1.创建数组 /* 构造函数 */ var arr1 = new Array(); //创建一个空数组 var arr1 = new Array(5); //创建指定长度数组(数 ...
- good design
canvas 效果麦当劳40周年纪念日 效果图 McDonald's 40th Anniversary 交互效果很流畅,赞!
- setTimeout和setInterval的区别以及如何写出效率高的倒计时
1.setTimeout和setInterval都属于js中的定时器,可以规定延迟时间再执行某个操作,不同的是setTimeout在规定时间后执行完某个操作就停止了,而setInterval则可以一直 ...