4

我正在使用该ChannelFactory<T>类型在 WCF Web 服务中创建通道WsHttpBinding,并且该服务使用用户名/密码组合进行身份验证。虽然我使用我的自定义验证器进行身份验证,但我在创建具有不同凭据的通道时遇到了困难。

考虑到创建的开销ChannelFactory<T>,我试图缓存它的单个实例并共享它,以便在我的应用程序的整个生命周期内创建多个通道。不幸的是,凭据似乎直接与工厂绑定,并且在创建通道后无法更改。

换句话说,如果我尝试这个:

factory.Credentials.UserName.UserName = "Bob";
factory.Credentials.UserName.Password = "password";

var channel1 = factory.CreateChannel();

factory.Credentials.UserName.UserName = "Alice"; // exception here
factory.Credentials.UserName.Password = "password";

var channel1 = factory.CreateChannel();

我收到一个异常,告诉我该UserName属性现在是只读的。

是否可以在这里实现任何类型的缓存,或者我基本上必须ChannelFactory为每个用户名缓存一个实例?

4

2 回答 2

8

正如 MSDN 上所记录的那样,这是不可能的(Credentials成为只读OpenChannelFactory)......如果你真的想这样做,你需要ChannelFactory像这样欺骗:

// step one - find and remove default endpoint behavior 
var defaultCredentials = factory.Endpoint.Behaviors.Find<ClientCredentials>();
factory.Endpoint.Behaviors.Remove(defaultCredentials); 


// step two - instantiate your credentials
ClientCredentials loginCredentials = new ClientCredentials();
loginCredentials.UserName.UserName = "Username";
loginCredentials.UserName.Password = "Password123";


// step three - set that as new endpoint behavior on factory
factory.Endpoint.Behaviors.Add(loginCredentials); //add required ones

另一种选择似乎是Close()ChannelFactory尝试更改Credentials.

否则,只需坚持为不同的凭据缓存不同的 ChannelFactories ...

于 2011-10-11T16:23:51.470 回答
3

您需要创建一个新的通道工厂。当工厂创建第一个通道时,它的属性变为只读(有些会抛出异常,如您所见;有些则更糟,您更改但没有任何反应,例如,如果您更改传递给的绑定元素中的某些属性CF 构造函数)。

于 2011-10-11T16:16:40.027 回答