今天想试一下WCF的异步调用的功能,就在一个自己原有的程序上使用。一般情况我都是自己手写代码的,但是这次我看了 张逸的《WCF服务编程》后按照书上的例子编写后发现会抛出一个异常,迫不得已,我只能用svcutil先来生成一个异步的客户端,然后比较代码之前的不同,终于发现问题的所在,现在把代码贴上:
Contracts:
namespace Contracts


{
[ServiceContract]
public interface IAdd

{
[OperationContract]
int Add(int x, int y);
}
}
Services:
namespace Services


{
public class AddService :IAdd

{
public int Add(int x, int y)

{
return x + y;
}
}
}

hosting:
namespace Hosting


{
public class CustomValidate : UserNamePasswordValidator

{
public override void Validate(string userName, string password)

{
Console.WriteLine(userName + " " + password);
if (userName != "user" || password != "pwd")

{
Console.WriteLine("error");
}
}
}
class Program

{
static void Main(string[] args)

{
using (ServiceHost host = new ServiceHost(typeof(Services.AddService)))

{
host.Opened += delegate

{
Console.WriteLine("opened");
};
host.Open();
Console.Read();
}
}
}
}
Client:

namespace Client


{
[ServiceContract(ConfigurationName = "Contracts.IAdd")]//问题的坐在,一定不能少
public interface IAdd

{
[OperationContract]
int Add(int x, int y);
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginAdd(int x, int y, AsyncCallback callback, object asyncState);
int EndAdd(IAsyncResult result);
}
public class AddClient : ClientBase<IAdd>, IAdd

{

public AddClient() : base()
{ }
public int Add(int x, int y)

{
return base.Channel.Add(x, y);
}
public IAsyncResult BeginAdd(int x, int y, AsyncCallback callback, object asyncState)

{
return Channel.BeginAdd(x, y, callback, asyncState);
}
public int EndAdd(IAsyncResult result)

{
return Channel.EndAdd(result);
}
}
class Program

{
static void Main(string[] args)

{
AddClient proxy = new AddClient();
proxy.ClientCredentials.UserName.UserName = "user";
proxy.ClientCredentials.UserName.Password = "pwd";
IAsyncResult asyncResult1 = proxy.BeginAdd(2, 3, null, null);
int sum = 0;
sum = proxy.EndAdd(asyncResult1);
Console.WriteLine(sum);
proxy.Close();

Console.Read();
}
}
}
Hosting的app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="behavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://10.6.235.138:6667/addservice"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="None"/>
</clientCertificate>
<serviceCertificate findValue="MyServer" storeLocation="CurrentUser" x509FindType="FindBySubjectName"/>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Hosting.CustomValidate,Hosting"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="binding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Services.AddService" behaviorConfiguration="behavior">
<endpoint bindingConfiguration="binding" address="net.tcp://10.6.235.138:6666/addservice" binding="netTcpBinding" contract="Contracts.IAdd"></endpoint>
</service>
</services>
</system.serviceModel>
</configuration>
client的app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="binding2">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint name="point" behaviorConfiguration="behavior3" bindingConfiguration="binding2" address="net.tcp://10.6.235.138:6666/addservice" binding="netTcpBinding" contract="Contracts.IAdd">
<identity>
<dns value="MyServer"/>
<!-- <certificate encodedValue="c2bb5a41d06ccc2b99bfb771d516728c0af33e78"/>-->
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="behavior3">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
因为是在原有的代码上做的,所以中间涉及到一些安全的部分,该部分请参考
Q.yuhen的文章。