看了一章的《WCF服务编程》,做一下练习。
先完成一个简单的例子,能实现客户端调用服务返回数据的功能,没有任何配置文件,只有代码。
1. 新建一个控制台程序(WCFHostConsole)和类库项目(WCFServiceLib),两个项目可以合并的,分开是为了后面测试其他宿主时用。
2. 两个项目都要添加System.ServiceModel引用,默认是不添加的。
3. 在WCFServiceLib中添加一个类MysService:
[ServiceContract]
public interface IMyContract
{
[OperationContract]
string MyMethod();
}
public class MyService:IMyContract
{
public string MyMethod()
{
return "Hello1";
}
}
4. 在WCFHostConsole中添加启动宿主的代码:
static void Main()
{
ServiceHost host=new ServiceHost(typeof(MyService));
host.Open();
Console.WriteLine("打开宿主:" + host);
Console.Read();
host.Close();
}
结果:
服务上要有终结点(EndPoint),EndPoint由Address,Contract,Binding组成。现在只有Contract,ServiceHost构造函数的参数中有Uri。改为:
Uri tcpBaseAddress=new Uri("net.tcp://localhost:8001/");
ServiceHost host=new ServiceHost(typeof(MyService), tcpBaseAddress);
程序可以启动了
5. 创建客户端程序(WCFClientConsole),添加服务引用。
1. 因为是同一个解决方案中,用Discover,没有发现可用的服务。
2. 等WCFHostConsole启动后,地址中填入net.tcp://localhost:8001/,也不行。
3. 使用VS自带的WcfTestClient.exe(位置在VS目录\Common7\IDE下面),添加服务,也不行。
这里有提示“确保公开元数据”,本来下面就是要公开元数据的。
6. 启用元数据交换功能
Uri tcpBaseAddress=new Uri("net.tcp://localhost:8001/");
ServiceHost host=new ServiceHost(typeof(MyService), tcpBaseAddress);
ServiceMetadataBehavior metadataBehavior=new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(metadataBehavior);
host.Open();
默认已经有5个行为了
仅仅是设置行为的HttpGetEnabled属性,不行。需要提供HttpGetUrl地址。
添加了metadataBehavior.HttpGetUrl=new Uri("http://localhost:8001/");
结果:
权限问题??书里没提到啊
查了一下,Win7系统(应该是Win7以后,我的是Win10)要Visual Studio以管理员的身份运行。
确实是管理员身份的问题,VS以管理员身份运行就可以了。
8001端口被占用了,改成metadataBehavior.HttpGetUrl=new Uri("http://localhost/");可以了。
不过单独运行生成的exe还是不行,
需要在项目中添加权限代码:
添加新建项,选择Application Manifest File,添加一个app.manifest文件,修改内容为
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
重新生成,可以点击exe运行了。
7. 客户端调用
1. 用WcfTestClient.exe调用
2. 添加服务引用
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IMyContract" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8001/" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IMyContract" contract="ServiceReference1.IMyContract"
name="NetTcpBinding_IMyContract">
<identity>
<userPrincipalName value="DESKTOP-CLV0P90\caiwanwei" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
3. 调用服务
static void Main(string[] args)
{
MyContractClient client = new MyContractClient();
string msg=client.MyMethod();
Console.WriteLine(msg);
Console.Read();
}
成功获取"holle1"。
后续在这基础上做其他试验。