Использование ChannelFactory<T> для создания каналов с разными учетными данными

Я использую 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 ответа

Решение

Как указано в 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 для разных учетных данных...

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

Другие вопросы по тегам