1.前言

上一篇,我们通过VS自带的模板引擎自动生成了一个wcf程序,接下来我们将手动实现一个wcf程序。由于应用程序开发中一般都会涉及到大量的增删改查业务,所以这个程序将简单演示如何在wcf中构建简单的增删改查服务。我们知道WCF是一组通讯服务框架,我将解决方案按大范围划分为服务端,客户端通过服务寄宿程序产生的代理来调用服务端的公开给客户端消费的方法。总个解决方案由五个项目工程:

  • Service:定义服务契约接口和实现服务契约,此项目类型为类库项目
  • Common:通用层定义数据访问的帮助类,此项目类型为类库项目
  • Entity:定义数据契约,也就是实体对象,此项目类型为类库项目
  • Host:服务寄宿程序,将Service服务程序寄宿在该程序中,此项目类型为控制台应用程序
  • Client:客户端程序,实现对服务的消费,此项目类型为web项目

2.实现程序

步骤一:建立数据库

为方便演示操作,我们建立一个简单的表,学生信息(Student),创建的脚本如下(此处我采用的是sql server数据库):

SET ANSI_NULLS ON
GO SET QUOTED_IDENTIFIERON
GO CREATE TABLE[dbo].[Student](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[Age] [int] NULL,
[Grade] [nvarchar](50) NULL,
[Address] [nvarchar](50) NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

步骤二:建立Common层

新建一个空白解决方案,名称为WcfDemo,创建完成后新增一个类库文件命名为Common,再添加一个数据库访问帮助类DbHelperSQL:代码如下:

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Data.Common;
using System.Collections.Generic; namespace Common
{
public class DbHelperSQL
{
public static string connectionString ="server=.;database=test;uid=sa;pwd=sa123"; public static int ExecuteSql(stringSQLString)
{
using (SqlConnection connection =new SqlConnection(connectionString))
{
using (SqlCommand cmd = newSqlCommand(SQLString, connection))
{
try
{
connection.Open();
int rows =cmd.ExecuteNonQuery();
return rows;
}
catch(System.Data.SqlClient.SqlException e)
{
connection.Close();
throw e;
}
}
}
} public static SqlDataReaderExecuteReader(string strSQL)
{
SqlConnection connection = newSqlConnection(connectionString);
SqlCommand cmd = newSqlCommand(strSQL, connection);
try
{
connection.Open();
SqlDataReader myReader =cmd.ExecuteReader(CommandBehavior.CloseConnection);
return myReader;
}
catch(System.Data.SqlClient.SqlException e)
{
throw e;
} } public static DataSet Query(stringSQLString)
{
using (SqlConnection connection =new SqlConnection(connectionString))
{
DataSet ds = new DataSet();
try
{
connection.Open();
SqlDataAdapter command =new SqlDataAdapter(SQLString, connection);
command.Fill(ds,"ds");
}
catch(System.Data.SqlClient.SqlException ex)
{
throw newException(ex.Message);
}
return ds;
}
} } }

步骤三:建立Entity层

在WcfDemo解决方案上新建一个名称为Entity的类库项目,添加对System.Runtime.Serialization的引用,创建服务的数据契约。新增Student类,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization; namespace Entity
{
[DataContract]
public class Student
{
[DataMember]
public int ID { get; set; } [DataMember]
public string Name { get; set; } [DataMember]
public int Age { get; set; } [DataMember]
public string Grade { get; set; } [DataMember]
public string Address { get; set; }
}
}
步骤四:建立Service层

此项目需要对Common和Entity的引用,再添加对System.ServiceModel的引用,以创建服务契约。在该项目中添加IStudent接口,定义服务契约接口,代码如下:

using System.Collections.Generic;
using System.ServiceModel;
using Entity; namespace Service
{
[ServiceContract]
public interface IStudent
{
[OperationContract]
List<Student> GetInfo(stringstrWhere); [OperationContract]
bool Add(Student model); [OperationContract]
bool Update(Student model); [OperationContract]
bool Delete(int id); [OperationContract]
bool Exist(int id);
}
}

再添加EFStudent类,实现对IStudent接口的实现,代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Common;
using Entity; namespace Service
{
public class EFStudent:IStudent
{
public List<Student>GetInfo(string strWhere)
{
List<Student> listData = newList<Student>();
string strSql = "select * fromstudent";
DataTable dt=DbHelperSQL.Query(strSql).Tables[];
if (null != dt &&dt.Rows.Count > )
{
for (int i = ; i <dt.Rows.Count; i++)
{
Student model = newStudent();
model.ID =Convert.ToInt32(dt.Rows[i]["ID"]);
model.Name =dt.Rows[i]["Name"].ToString();
model.Age =Convert.ToInt32(dt.Rows[i]["Age"]);
model.Grade =dt.Rows[i]["Grade"].ToString();
model.Address =dt.Rows[i]["Address"].ToString();
listData.Add(model);
}
}
return listData;
} public bool Add(Student model)
{
StringBuilder strSql = newStringBuilder();
strSql.Append(" insert intostudent values ");
strSql.Append(" ( ");
strSql.Append(" " +model.ID + ", ");
strSql.Append(" '" +model.Name + "', ");
strSql.Append(" " +model.Age + ", ");
strSql.Append(" '" +model.Grade + "', ");
strSql.Append(" '" +model.Address + "' ");
strSql.Append(" ) "); int rows =DbHelperSQL.ExecuteSql(strSql.ToString());
if (rows > )
{
return true;
}
else
{
return false;
}
} public bool Update(Student model)
{
StringBuilder strSql = newStringBuilder();
strSql.Append(" update studentset ");
strSql.Append(" Name= '"+ model.Name + "', ");
strSql.Append(" Age= " +model.Age + ", ");
strSql.Append(" Grade= '" +model.Grade + "', ");
strSql.Append(" Address='" + model.Address + "' ");
strSql.Append(" WhereID=" + model.ID + " "); int rows =DbHelperSQL.ExecuteSql(strSql.ToString());
if (rows > )
{
return true;
}
else
{
return false;
}
} public bool Delete(int id)
{
StringBuilder strSql = new StringBuilder();
strSql.Append(" delete fromstudent where ID=" + id + " ");
int rows =DbHelperSQL.ExecuteSql(strSql.ToString());
if (rows > )
{
return true;
}
else
{
return false;
}
} public bool Exist(int id)
{
StringBuilder strSql = newStringBuilder();
strSql.Append(" select ID fromstudent where ID=" + id + " ");
DataTable dt =DbHelperSQL.Query(strSql.ToString()).Tables[];
if (null != dt &&dt.Rows.Count > )
{
return true;
}
else
{
return false;
}
}
}
}

步骤五:建立Host层,对Service进行寄宿

此项目需要对Service项目的引用,并添加对using System.ServiceModel的引用,添加寄宿的服务配置文件App.config,代码如下:

<?xmlversion="1.0"?>
<configuration>
<system.serviceModel>
<services>
<servicename="Service.EFStudent"behaviorConfiguration="EFStudentBehavior">
<host>
<baseAddresses>
<addbaseAddress="http://127.0.0.1:1234/EFStudent/"/>
</baseAddresses>
</host> <endpoint address="" binding="wsHttpBinding"contract="Service.IStudent"/>
<endpoint address="mex"binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services> <behaviors>
<serviceBehaviors>
<behaviorname="EFStudentBehavior">
<serviceMetadatahttpGetEnabled="True"/>
<serviceDebugincludeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel> <startup>
<supportedRuntime version="v4.0"sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

服务寄宿程序Host的Program.cs的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Service; namespace Host
{
class Program
{
static void Main(string[] args)
{
try
{
using (ServiceHost host = newServiceHost(typeof(EFStudent)))
{
host.Opened += delegate
{
Console.WriteLine("StudentService已经启动,按任意键终止!");
}; host.Open();
Console.Read();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
}
}

此时,可以编译程序,找到Host项目生成目录,运行Host.exe,就可以对服务进行寄宿,如果寄宿成功,在浏览器中输入http://127.0.0.1:1234/EFStudent地址,就可以看到如下图所示页面:

步骤六:建立Web客户端

新建一个空Client的Web引用程序,添加对服务的引用,输入刚才在浏览器中输入的地址,然后点击发现前往按钮就可以发现服务了,点击确定添加对服务的引用,vs会自动生成对服务的应用配置文件和代理类,如果需要手动生成,可以参考WCF初探—1:认识wcf。添加MainForm.aspx页面,前端代码如下:

<%@ PageLanguage="C#" AutoEventWireup="true"CodeBehind="MainForm.aspx.cs"EnableEventValidation="false" Inherits="Client.MainForm" %>

<!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title></title>
<scripttype="text/javascript">
var prevselitem = null;
function selectx(row) {
if (prevselitem != null) {
prevselitem.style.backgroundColor = '#ffffff';
}
row.style.backgroundColor ='PeachPuff';
prevselitem = row; }
</script>
</head>
<body>
<form id="form1"runat="server">
<asp:GridView ID="GridView1"runat="server" AutoGenerateColumns="False"
onrowdeleting="GridView1_RowDeleting"
onrowdatabound="GridView1_RowDataBound"
onrowcommand="GridView1_RowCommand">
<Columns>
<asp:TemplateFieldHeaderText="编号">
<ItemTemplate>
<asp:LabelID="lbl_id" runat="server" Text='<%#Bind("ID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundFieldDataField="Name" HeaderText="姓名" />
<asp:BoundField DataField="Age"HeaderText="年龄"/>
<asp:BoundFieldDataField="Grade" HeaderText="年级" />
<asp:BoundFieldDataField="Address" HeaderText="家庭地址" />
<asp:CommandFieldHeaderText="删除"ShowDeleteButton="True" />
<asp:TemplateFieldHeaderText="编辑">
        <ItemTemplate>
            <asp:LinkButtonID="lbtID"
CommandName="lbtn" runat="server"ForeColor="Blue" Text="编辑">
</asp:LinkButton>
          </ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView> <p>编号<asp:TextBox ID="txt_id"runat="server"></asp:TextBox></p>
<p>姓名<asp:TextBox ID="txt_name"runat="server"></asp:TextBox></p>
<p>年龄<asp:TextBox ID="txt_age"runat="server"></asp:TextBox></p>
<p>年级<asp:TextBox ID="txt_grade"runat="server"></asp:TextBox></p>
<p>家庭地址<asp:TextBox ID="txt_address"runat="server"></asp:TextBox></p>
<asp:Button ID="btnAdd"runat="server" Text="保存" onclick="btnAdd_Click" />
</form> </body>
</html>

后台代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Client.ServiceReference; namespace Client
{
public partial class MainForm :System.Web.UI.Page
{
StudentClient proxy = newStudentClient();
protected void Page_Load(object sender,EventArgs e)
{
if (!Page.IsPostBack)
{
BindData();
}
} private void BindData()
{
Student[] listData =proxy.GetInfo("");
this.GridView1.DataSource =listData.ToList();
this.GridView1.DataBind();
} protected void btnAdd_Click(objectsender, EventArgs e)
{
Student model = new Student();
model.ID =Convert.ToInt32(this.txt_id.Text);
model.Name = this.txt_name.Text;
model.Age =Convert.ToInt32(this.txt_age.Text);
model.Grade = this.txt_grade.Text;
model.Address =this.txt_address.Text;
if (proxy.Exist(model.ID))
{
proxy.Update(model);
}
else
{
proxy.Add(model);
} BindData();
} protected voidGridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{ int id =Convert.ToInt16(((GridView1.Rows[e.RowIndex].FindControl("lbl_id") asLabel).Text));
bool flag = proxy.Delete(id);
if (flag)
{
Response.Write("<Script>alert(' 删除成功!')</Script> ");
BindData();
}
else
{
Response.Write("<Script>alert(' 删除失败!')</Script> ");
}
} protected voidGridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType ==DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onclick", e.Row.ClientID.ToString() +".checked=true;selectx(this)");//点击行变色 }
} protected voidGridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName =="lbtn")
        {
          GridViewRow gvrow =(GridViewRow)(((LinkButton)e.CommandSource).NamingContainer); //获取被点击的linkButton所在的GridViewRow
          int index =gvrow.RowIndex; //获取到行索引 RowIndex this.txt_id.Text =(GridView1.Rows[index].Cells[].FindControl("lbl_id") asLabel).Text.Trim();
        this.txt_name.Text=GridView1.Rows[index].Cells[].Text.Trim();
this.txt_age.Text =GridView1.Rows[index].Cells[].Text.Trim();
this.txt_grade.Text =GridView1.Rows[index].Cells[].Text.Trim();
this.txt_address.Text =GridView1.Rows[index].Cells[].Text.Trim();         }     
} }

到此,我们完成了一个手动编写的WCF程序,我没有讲太多的原理,这个在网络上可以搜索到很多对概念的解释,我这个以实际操作为准,对平时学习的一个积累,如有不当之处,欢迎指出,共同学习进步。

WCF初探-2:手动实现WCF程序的更多相关文章

  1. WCF初探-1:认识WCF

    1.WCF是什么? WindowsCommunication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,它是.NET框架的一部分,由.NET Framework 3. ...

  2. WCF初探文章列表

    WCF初探-1:认识WCF WCF初探-6:WCF服务配置 WCF初探-2:手动实现WCF程序 WCF初探-7:WCF服务配置工具使用 WCF初探-3:WCF消息交换模式之单向模式 WCF初探-8:W ...

  3. 手动实现WCF[转]

    由于应用程序开发中一般都会涉及到大量的增删改查业务,所以这个程序将简单演示如何在wcf中构建简单的增删改查服务.我们知道WCF是一组通讯服务框架,我将解决方案按大范围划分为服务端,客户端通过服务寄宿程 ...

  4. WCF初探-10:WCF客户端调用服务

    创建WCF 服务客户端应用程序需要执行下列步骤: 获取服务终结点的服务协定.绑定以及地址信息 使用该信息创建 WCF 客户端 调用操作 关闭该 WCF 客户端对象 WCF客户端调用服务存在以下特点: ...

  5. 创建一个简单的WCF程序2——手动开启/关闭WCF服务与动态调用WCF地址

    一.创建WCF服务器 1.创建WCF服务器的窗体应用程序 打开VS2010,选择文件→新建→项目菜单项,在打开的新建项目对话框中,依次选择Visual C#→Windows→Windows窗体应用程序 ...

  6. 【Win 10应用开发】手动调用WCF服务

    调用服务最简单的方法就是,直接在VS里面添加服务引用,输入服务的地址即可,无论是普通Web服务,还是WCF服务均可.VS会根据获取到的元数据,自动生成客户端代码. 如果服务的调用量很大,应用广泛,可以 ...

  7. WCF初探-28:WCF中的并发

    理解WCF中的并发机制 在对WCF并发机制进行理解时,必须对WCF初探-27:WCF中的实例化进行理解,因为WCF中的并发特点是伴随着服务实例上下文实现的.WCF的实例上下文模型可以通过Instanc ...

  8. WCF初探-27:WCF中的实例化

    理解WCF中的实例化机制 “实例化”是指对用户定义的服务对象以及与其相关的 InstanceContext 对象的生存期的控制.也就是说我们的客户端程序在调用服务端方法时,需要实例化一个服务端代理类对 ...

  9. WCF初探-26:WCF中的会话

    理解WCF中的会话机制 在WCF应用程序中,会话将一组消息相互关联,从而形成对话.会话”是在两个终结点之间发送的所有消息的一种相互关系.当某个服务协定指定它需要会话时,该协定会指定所有调用(即,支持调 ...

随机推荐

  1. php操作Mysql 以及封装常用的函数 用外连接连接3个表的案例

    <?php header("content-type;text/html;charset=utf-8"); //数据库连接define('DB_HOST','localhos ...

  2. 响应式布局1--媒体查询和-webkit-min-device-pixel-ratio

    -webkit-min-device-pixel-ratio其实就是这个玩意 window.devicePixelRatio是设备上物理像素和设备独立像素(device-independent pix ...

  3. [原创]java WEB学习笔记99:Spring学习---Spring Bean配置:自动装配,配置bean之间的关系(继承/依赖),bean的作用域(singleton,prototype,web环境作用域),使用外部属性文件

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. 手机触摸touch事件

    1.Touch事件简介 pc上的web页面鼠 标会产生onmousedown.onmouseup.onmouseout.onmouseover.onmousemove的事件,但是在移动终端如 ipho ...

  5. Frag(匹配跟踪)

    ‘碎片’(Frag)跟踪是目标跟踪里的一种通过‘部分‘匹配识别的方法,其目标模板是通过图像多个碎片和块来描述.块是任意的,不基于目标模型的(与传统的基于’部分‘的方法不一样,比如人体的四肢与躯干的跟踪 ...

  6. confluence重置admin密码

    复方法: 1. 运行此sql 找到你的管理员帐户: select u.id, u.user_name, u.active from cwd_user u join cwd_membership m o ...

  7. css3实现轮播

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. 关于SQL Server 中连接查询Join的几种常见用法

    现有A.B .C 三个表,A中的ID=B中的ID,B中的ID=C中的ID:也就是:A.ID=B.ID,B.ID=C.ID; 一. Inner Join 把两个表链接一起查 Select * from ...

  9. 用代码来理解 C#委托与事件

    C#中委托是什么?事件是委托吗? 1.委托是讲方法作为参数代入另一个方法中, 委托可以理解为指向一个函数的引用. class Program { public delegate void Delega ...

  10. App.xaml.cs

    using System.Windows; namespace HelloWorld { /// <summary> /// Interaction logic for App.xaml ...