Использование 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).