朋友炒股两个月赚了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>

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

添加:

修改:

列表及删除:

八、源码下载

点我下载本文章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. 在dede:arclist、dede:list等标签中调用附加字段

    {dede:list perpage='20'} <div class="f-con01"> <div class="f-con01-l"&g ...

  2. 2017年1月3日 星期二 --出埃及记 Exodus 21:29

    2017年1月3日 星期二 --出埃及记 Exodus 21:29 If, however, the bull has had the habit of goring and the owner ha ...

  3. mysql 替换某个字段中的某个字符

    遇到这么个情况: 比如: Msql里面的某个表的某个字段里面存储的是一个人的地址,有一天这个地址的里面的某个地 名变了,那么他的地址也就要变: 比如: 原来是: number              ...

  4. PHPStorm 与 XDebug 配置

    XDebug 配置 环境 Nginx 1.4.7 32 bit PHP 5.4.25 32 bit Windows 10 64 bit 下载 PHP 5.4 VC9 (32 bit)[nts版本] 配 ...

  5. 新版微信h5视频自动播放

    微信最近升级了新版本,直播视频不能自动播放,经过了一番探索,发现下列方法可以实现自动播放. if (typeof WeixinJSBridge == "undefined") { ...

  6. Download Oracle Forms 6i

    To download Oracle Forms Developer 6i from Oracle click this link http://download.oracle.com/otn/nt/ ...

  7. gravity与layout_gravity的区别

    android:gravivty 控件的内容显示位置 android:layout_gravity 控件在屏幕的布局位置,相对于容器或者父控件的位置

  8. php : 常用函数

    常用函数: <?php /** * 获取客户端IP * @return [string] [description] */ function getClientIp() { $ip = NULL ...

  9. 1006. Sign In and Sign Out (25)

    At the beginning of every day, the first person who signs in the computer room will unlock the door, ...

  10. Android导航栏菜单强制转换

    private void getOverflowMenu() { ViewConfiguration viewConfig = ViewConfiguration.get(this); try { F ...