Использование ChannelFactory <T>для создания каналов с разными учетными данными - PullRequest
3 голосов
/ 11 октября 2011

Я использую тип ChannelFactory<T> для создания каналов в веб-службе WsHttpBinding WCF, а служба использует комбинацию имени пользователя и пароля для аутентификации. Пока у меня работает аутентификация с использованием моего пользовательского валидатора, у меня возникают трудности при создании каналов с разными учетными данными.

Учитывая накладные расходы на создание 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 для каждого имени пользователя?

Ответы [ 2 ]

7 голосов
/ 11 октября 2011

Как указано в MSDN , это невозможно напрямую (Credentials становится доступным только для чтения Open из ChannelFactory) ... если вы действительно хотите это сделать, вам нужно будет обмануть 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 для разных учетных данных ...

2 голосов
/ 11 октября 2011

Вам нужно будет создать новую фабрику каналов.Когда фабрика создает первый канал, его свойства становятся доступными только для чтения (некоторые выдают исключение, как вы видите; некоторые другие хуже, в которых вы меняете, но ничего не происходит, например, если вы изменяете какое-то свойство в элементе привязки, который вы передаликонструктор CF).

...