第一个WCF程序(最小实现)
环境:Microsoft Visual Studio 2017
注意事项:右键“以管理员身份”启动VS。
目标:实现一个加法运算,并在服务器端D盘新建一个文件夹。
一、服务器端创建WCF服务
1、右键启动VS;
2、“文件”-“新建”-“项目”,Visual C#->Windows经典桌面,右侧的“类库(.net Framework)”,新建一个项目“SytWCFService”;
3、右键“SytWCFService”->添加->新建项,选择“接口”;右键“Interface1”选择重命名,为“ISytService”;修改文件名为“ISytService”;修改为public interface;
4、添加引用“System.ServiceModel”:右键添加,引用;
5、完成以下代码(创建接口):
using System.ServiceModel; namespace SytWCFService { /// <summary> /// 定义服务契约:通过接口实现契约 /// </summary> [ServiceContract(Name = "SytService")] public interface ISytInterface { /// <summary> /// 定义操作契约 /// </summary> /// <param name="num1"></param> /// <param name="num2"></param> /// <returns></returns> [OperationContract(Name = "AddOperation")] double AddOperation(double num1, double num2); [OperationContract(Name = "CreateDir")] bool CreateDir(string dir); } }
6、实现接口:新建类SytService : ISytService,继承ISytService接口,在接口名上点左键,可以一键“实现接口”。
7、完成以下代码(实现接口):
using System.IO; namespace SytWCFService { public class SytService : ISytService { public double AddOperation(double num1, double num2) { return num1 + num2; } public bool CreateDir(string dir) { if (!Directory.Exists(dir))//如果不存在就创建 dir 文件夹 { Directory.CreateDirectory(dir); return true; } else { return false; } } } }
二、定义宿主,寄宿WCF服务
WCF服务典型的宿主包括以下四种:
"Self-Hosting" in a Managed Application(自托管宿主)
Managed Windows Services(Windows Services宿主)
Internet Information Services(IIS宿主)
Windows Process Activation Service(WAS宿主)
1、以自托管宿主的方式寄宿。
1.1 通过代码的方式配置WCF服务
略。
1.2 通过配置文件的方式配置WCF服务
(1)添加一个console控制台项目“ConsoleHosting”,完成以下代码:
using System.ServiceModel; using SytWCFService; namespace ConsoleHosting { class Program { static void Main(string[] args) { //如果采用了配置文件的方式,服务寄宿代码将会得到极大的精简,只需包含下面几行代码: using (ServiceHost host = new ServiceHost(typeof(SytService))) { host.Open(); Console.WriteLine("服务已启动"); Console.Read(); } //通过代码的方式配置WCF服务 //using (ServiceHost host = new ServiceHost(typeof(SytService), new Uri("http://127.0.0.1:9099/CalculateWcfService"))) //{ // BasicHttpBinding bind = new BasicHttpBinding // { // Name = "basichttpbinding" // }; // host.AddServiceEndpoint(typeof(ICalculateService), bind, "CalculateWcfService"); // if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null) // { // ServiceMetadataBehavior behavior = new ServiceMetadataBehavior() // { // HttpGetEnabled = true // }; // host.Description.Behaviors.Add(behavior); // } // host.AddServiceEndpoint(typeof(IMetadataExchange), bind, "mex"); // if (host.State != CommunicationState.Opened) // { // host.Open(); // } // Console.WriteLine("服务已启动"); // Console.Read(); //} } } }
(2)在“ConsoleHosting”项目中添加一个app.config应用程序配置文件,此时配置信息为空。
右键点击“app.config”,选择“编辑WCF配置”,弹出“WCF服务配置编辑器”,如下图:
点击右侧“新建服务”或者右键“服务”,选择“新建服务”;
在弹出的“新建服务元素向导”中,点击“浏览”,双击“SytWCFService\bin\Debug”目录下生成的“SytWCFService.dll”,在“类型浏览器”对话框中会出现“SytWCFService.SytService”:
http://127.0.0.1:9098/MyWcfService
关闭向导时,选择保存更改:
这时得到的配置文件内容为:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <services> <service name="SytWCFService.SytService"> <endpoint address="http://127.0.0.1:9098/MyWcfService" binding="basicHttpBinding" bindingConfiguration="" contract="SytWCFService.ISytService" /> </service> </services> </system.serviceModel> </configuration>
改成这样了,哈哈
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="basicHttpBinding" /> </basicHttpBinding> </bindings> <services> <service behaviorConfiguration="MyBehavior" name="SytWCFService.SytService"> <endpoint address="http://127.0.0.1:9098/MyWcfService" binding="basicHttpBinding" bindingConfiguration="" contract="SytWCFService.ISytService" /> <host> <baseAddresses> <add baseAddress="http://localhost:9098/"/> <add baseAddress="net.tcp://localhost:10001/"/> </baseAddresses> </host> </service> </services> <!--行为--> <behaviors> <serviceBehaviors> <behavior name="MyBehavior"> <!-- httpGetEnabled - bool类型的值,表示是否允许通过HTTP的get方法获取sevice的WSDL元数据 --> <serviceMetadata httpGetEnabled="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
再改,改成如下情况,地址栏输入“http://localhost:9099/”可以查看相关信息:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="basicHttpBinding" /> </basicHttpBinding> </bindings> <services> <service behaviorConfiguration="" name="SytWCFService.SytService"> <!--<endpoint address="MyWcfService" binding="basicHttpBinding" bindingConfiguration="" contract="SytWCFService.ISytService" />--> <endpoint address="MyWcfService" binding="basicHttpBinding" contract="SytWCFService.ISytService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <!--<endpoint address="http://127.0.0.1:9099/SytWCFService" binding="basicHttpBinding" contract="SytWCFService.ISytService"></endpoint> <endpoint address="net.tcp://localhost:10001/CalculateWcfService" binding="netTcpBinding" contract="SytWCFService.ISytService"></endpoint>--> <host> <baseAddresses> <add baseAddress="http://localhost:9099/"/> </baseAddresses> </host> </service> </services> <!--行为--> <behaviors> <serviceBehaviors> <!--<behavior name="MyBehavior">--> <behavior > <!-- httpGetEnabled - bool类型的值,表示是否允许通过HTTP的get方法获取sevice的WSDL元数据 --> <!--<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:9099/s"/>--> <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
两个项目都编译通过后,找到“ConsoleHosting.exe”,右键管理员运行,要想在VS中运行,需要以管理员身份运行VS。如下图:
在ConsoleHosting.exe运行的情况下,新建一个Windows项目作为客户端,来调用服务,console或者Form窗体程序都可以。
新建Form窗体程序“WindowsFormsForWCF”,右键点击“WindowsFormsForWCF”,选择“添加”->“服务引用”,打开“添加服务引用”对话框:
输入地址:http://localhost:9099/->点击“转到”,可以看到服务下出现“SytService”,下边改名为“ServiceReference1syt”,如下图:
窗体上添加两个按钮,代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsForWCF { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //引用服务 ServiceReference1syt.SytServiceClient myclient = new ServiceReference1syt.SytServiceClient(); MessageBox.Show(myclient.AddOperation(1,2).ToString()); } private void button2_Click(object sender, EventArgs e) { //引用服务 ServiceReference1syt.SytServiceClient myclient = new ServiceReference1syt.SytServiceClient(); myclient.CreateDir("d:\\aaaaaa"); MessageBox.Show(myclient.AddOperation(1,2).ToString()); } } }
成功!