一、前言
在上一篇文章里我们已经了解到如何创建及部署一个简单的WCF服务,如果不了解的朋友可以先跳转上篇文章:创建及部署WCF,所以对于重复的内容这里就不细说了,这篇文章主要介绍如何在MVC框架中使用WCF。
二、Demo说明
1)Demo的 “Service端”以本机IIS为宿主,“Client端”以MVC项目为例。
2)Demo的“Service端”提取数据采用初学者比较容易接受的分层结构进行搭建,分别分为服务层、实体层、数据层。
引用关系如下图所示:

3)Demo以数据库为SqlServer,表UserDemo为例(sql语句在下载的压缩包中
creatTable.sql
),表结构如下所示:
字段名 | 列名 | 数据类型 | 约束 | 生成方式 |
---|---|---|---|---|
用户编号 | UserID | int | 主键,必须输入 | 自动增+1 |
姓名 | Name | varchar(200) | 非必须输入 | 人工输入 |
密码 | Password | varchar(200) | 非必须输入 | 人工输入 |
描述 | Discribe | varchar(800) | 非必须输入 | 人工输入 |
提交时间 | SubmitTime | datetime | 非必须输入 | 人工输入 |
三、创建WCF服务Service端
1)创建WCF应用程序命名为:WCF.Demo.Service,如下图:

2)删除默认文件IService.cs与Service.svc。并分别创建增、删、改、查”Add.svc”、“Save.svc”、“Remove.svc”、“Get.svc,Search.svc”,分别对应4个功能的服务应用程序WCF服务应用程序,并创建数据操作层和数据实体层,如下图:

3)贴上部分代码解析一下作用,本例子的全部代码可拉到下文下载。
Model层里的User是需要注解为[DataContract]
,以及成员需要用[DataMember]
,这里涉及一个知识点,数据契约(DataContract) 服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型。一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务端和客户端之间传送。
只有声明为DataContract的类型的对象可以被传送,且只有成员属性会被传递,成员方法不会被传递。WCF对声明为DataContract的类型提供更加细节的控制,可以把一个成员排除在序列化范围以外,也就是说,客户端程序不会获得被排除在外的成员的任何信息,包括定义和数据。默认情况下,所有的成员属性都被排除在外,因此需要把每一个要传送的成员声明为DataMember。
DataMember还有以下参数,它们的含义分别如下。
-
IsRequired
:值为true时,要求序列化引擎检查对象是否存在该值;若无,则会有异常抛出。 -
Order
:bool类型值,值为true时,序列化和反序列化过程将会按成员定义的顺序进行,这对依赖于成员位置的反序列化过程无比重要。 -
EmitDefaultvalue
:为成员属性设置一个默认值。
namespace WCF.Demo.Model
{
[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; }
}
}
其实的也没什么的,就是在DAL创建一个sqlHelper类,以及一个User的方法类来操作数据库数据,至于创建的WCF服务程序也就是对DAL层的调用,提醒一下要调用解决方案内的其他程序集记得添加引用。

-----------------------------------以下是:IGet.cs-------------------------------
namespace WCF.Demo.Service
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IGet”。
[ServiceContract]
public interface IGet
{
[OperationContract]
List<Model.User> DoWork();
}
}
----------------------------------以下是:Get.svc--------------------------------------
namespace WCF.Demo.Service
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Get”。
// 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Get.svc 或 Get.svc.cs,然后开始调试。
public class Get : IGet
{
List<Model.User> IGet.DoWork()
{
return DAL.User.GetUsers();
}
}
}
四、部署WCF服务到IIS
具体步骤:到IIS添加网站,然后将此WCF程序的路径填入网站路径,起个网站名,和设个端口,就基部署完成了,至于具体图文步骤的话可参考我上篇文章,这里就不细说了。
五、创建Client端MVC应用程序
新建一个空白的MVC项目WCF.Demo.Client,然后新建一个Demo控制器。

由于数据服务已经交给了WCF,所以这里就不需要再添加Model层代码,只需要调用WCF,在控制器添加几个Action操作,以及添加其对应的视图,所以得先添加WCF服务引用,

如下图将所有的服务都引用进来,

然后再增加对应控制器的调用WCF代码,贴上部分代码。
public class DemoController : Controller
{
//获取列表
public ActionResult Get()
{
GetClient getClient = new GetClient();
var user=getClient.DoWork();
return View(user);
}
//添加
public ActionResult Add()
{
return View();
}
//添加
[HttpPost]
public ActionResult Add(AddService.User user)
{
AddClient addClient = new AddClient();
user.SubmitTime = DateTime.Now;
addClient.DoWork(user);
return RedirectToAction("Get");
}
}
这获取用户数据的主页Get视图代码。
@model IEnumerable<WCF.Demo.Client.GetService.User>
@{
ViewBag.Title = "Get";
}
<h2>Get</h2>
<p>
@Html.ActionLink("添加用户", "Add")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.UserID)
</th>
<th>
@Html.DisplayNameFor(model => model.UserName)
</th>
<th>
@Html.DisplayNameFor(model => model.Password)
</th>
<th>
@Html.DisplayNameFor(model => model.Discribe)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmitTime)
</th>
</tr>
@foreach(var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelitem => item.UserID)
</td>
<td>
@Html.DisplayFor(modelitem => item.UserName)
</td>
<td>
@Html.DisplayFor(modelitem => item.Password)
</td>
<td>
@Html.DisplayFor(modelitem => item.Discribe)
</td>
<td>
@Html.DisplayFor(modelitem => item.SubmitTime)
</td>
<td>
@Html.ActionLink("编辑", "Save", new { userid = item.UserID }) |
@Html.ActionLink("详情", "Search", new { userid = item.UserID }) |
@Html.ActionLink("删除", "Remove", new { userid = item.UserID })
</td>
</tr>
}
</table>
这些调用相对都是非常简单的,需要注意一点的就是对应视图与控制器的模型绑定,由于这里不用MVC原有Model层,而调用WCF的Model层,因此模型绑定也是针对WCF的,MVC本身的Model层就当不存在吧,如:
@model IEnumerable<WCF.Demo.Client.GetService.User>
六、最终效果图



最后如果文章对你有一点帮助的话,就点个赞或喜欢吧
网友评论