一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情。
服务器端
1. 创建 WCF 服务应用程序
1.1 WCF 应用程序的目录结构(以创建的时候,程序名为 默认的 WcfService1 为例)
-
IService1.cs : 服务的接口的定义
- [ServiceContract] : 服务协定
- [OperationContract] : 操作协定:接口中每定义一个方法之前,都要在这个定义的方法之前加上这个操作协定,否则该方法不能被调用
// 案例: 定义一个 sayHello 的方法 [ServiceContract] public interface IService1 { [OperationContract] string sayHello(string name); //...省略部分代码... // TODO: 在此添加您的服务操作 } -
Service1.svc : 服务
-
Service1.svc.cs : 实现 服务中定义的接口 的类
// 案例:实现上面定义的那个 sayHello 方法 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。 // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。 public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { // ...省略部分代码.... } public string sayHello(string name) { return "hello"+ name; } }
-
-
Web.config : 配置信息
- : 协议绑定节点
<!-- Web.config 的部分代码--> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior> <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false --> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <protocolMapping> <add binding="basicHttpsBinding" scheme="https" /> </protocolMapping> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> <!-- 若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。 在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。 --> <directoryBrowse enabled="true"/> </system.webServer>
客户端
创建一个 WPF 应用程序( 默认命名 WpfApp1 )
1. 添加服务的引用
-
右键引用 ---> 选择 “添加服务引用” ---> 将服务程序运行之后生成的地址给复制到这里 ----> 对该引用进行命名(一般选择默认的名称 这里是 ServiceReference1 )---> 确定 ====> 即添加完成
-
添加完成之后,右侧会多一部分内容:
Connected Services (目录) ---> ServiceReference1 (前面目录下的文件)
-
添加完成之后,在 App.config 配置文件里面会增加一部分内容
<!--添加服务引用时候自动添加的内容-->
<system.serviceModel>
<bindings>
<basicHttpBinding>
<!--单向绑定-->
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
</bindings>
<client>
<!--终结点-->
<!--下面的这个 bindingConfiguration 属性的值为 上面我们定义的 绑定的名字-->
<!--binding 的属性值为 绑定的方式-->
<endpoint address="http://localhost:50490/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
-
点击右侧新生成的
ServiceReference1文件 会看到:服务端的方法都在 客户端代理类的下面:(这也是为什么 后文 我们要通过 客户端代理类来调用方法)
2. 调用服务中的方法
-
首先需要引入命名空间:
using WpfApp1.ServiceReference1 ;注意:如果我们的服务端和客户端是在同一个解决方案下面的话,这个命名空间的引入,系统会在我们添加引用的时候自动帮我们引入的;但是在不同的解决方案下面的话,就需要我们进行手动引入了
-
通过 客户端代理类 来调用服务中的方法
- 客户端代理类是在 我们创建的 引用的命名空间下面的,所以如果我们没有在前面引入命名空间的话,是会报错的
- 客户端代理类的类名 一般是 我们创建的服务程序的名字加上一个
Client,就比如说我们这里的Service1Client
示例代码如下:
<!-- 图形界面的主要代码 -->
<Grid>
<TextBox Name="TextBox1" HorizontalAlignment="Left" Height="66" Margin="81,72,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="375"/>
<Button Name="btn1" Content="Button" HorizontalAlignment="Left" Height="58" Margin="121,215,0,0" VerticalAlignment="Top" Width="169" Click="Btn1_Click"/>
</Grid>
// 定义 wpf 界面中的 按钮的单击事件
private void Btn1_Click(object sender, RoutedEventArgs e)
{
//创建客户端代理类的对象
Service1Client client = new Service1Client();
// 调用 服务中的 sayHello 方法
TextBox1.Text = client.sayHello( "aaa");
}
注意事项
- 一定要先打开服务程序,再运行 客户端程序(如果服务程序未运行,运行客户端程序,系统会在客户端程序中的调用服务程序的代码的地方报错的!!!)
- 我们调用服务中的方法,使用的是 客户端代理类 对象来调用的;在我们使用 代理类对象之前,一定要 添加服务应用和引入对应的命名空间