Как настроить URL-адрес веб-службы ASMX из удаленного источника
Мы работаем над устаревшим корпоративным приложением на C#. Его клиент использует несколько веб-сервисов, чьи URL-адреса, среди множества других настроек, считываются из локального файла app.config. Мы хотим перенести эти настройки в глобальную БД, чтобы упростить их управление. Однако я не могу понять, как (и можно ли) перенести URL-адреса веб-служб. Они читаются из клиентского кода службы, сгенерированного VS, и я не могу найти способ сказать VS использовать другого поставщика настроек, чем тот, который сгенерирован в Settings.Designer.cs
,
Мы можем заменить сервисный фасад Url
свойство со значением, которое мы хотим, после его создания - это решение, используемое в настоящее время в нескольких местах кода. Однако я не хотел бы касаться каждой части нашей кодовой базы, где используются какие-либо из этих сервисов (сейчас и в будущем). Еще меньше я хотел бы изменить сгенерированный код.
Должно быть лучшее, чище, безопаснее решение - или есть?
Кстати, наше приложение работает на.NET 2.0, и мы не будем переходить на более новые версии платформы в обозримом будущем.
1 ответ
Refernce.cs
Файл, сгенерированный Visual Studio, указывает, что URL-адрес веб-службы будет получен из настроек:
this.Url = global::ConsoleApplication1.Properties.
Settings.Default.ConsoleApplication1_net_webservicex_www_BarCode;
Я считаю, что John Saunders дал вам замечательное предложение в своем комментарии. Тебе необходимо SettingsProvider
класс который:
... определяет механизм хранения данных конфигурации, используемых в архитектуре настроек приложения..NET Framework содержит единственный поставщик параметров по умолчанию LocalFileSettingsProvider, который сохраняет данные конфигурации в локальной файловой системе. Однако вы можете создать альтернативные механизмы хранения, наследуя абстрактный класс SettingsProvider. Поставщик, используемый классом-оболочкой, определяется путем украшения класса-оболочки параметром SettingsProviderAttribute. Если этот атрибут не указан, используется значение по умолчанию LocalFileSettingsProvider.
Я не знаю, насколько вы продвинулись в этом подходе, но все должно пройти довольно просто:
Создать
SettingsProvider
учебный класс:namespace MySettings.Providers { Dictionary<string, object> _mySettings; class MySettingsProvider : SettingsProvider { // Implement the constructor, override Name, Initialize, // ApplicationName, SetPropertyValues and GetPropertyValues (see step 3 below) // // In the constructor, you probably might want to initialize the _mySettings // dictionary and load the custom configuration into it. // Probably you don't want make calls to the database each time // you want to read a setting's value } }
Расширить определение класса для проекта
YourProjectName.Properties.Settings
частичный класс и украсить его сSettingsProviderAttribute
:[System.Configuration.SettingsProvider(typeof(MySettings.Providers.MySettingsProvider))] internal sealed partial class Settings { // }
В переопределенном
GetPropertyValues
метод, вы должны получить сопоставленное значение из_mySettings
толковый словарь:public override SettingsPropertyValueCollection GetPropertyValues( SettingsContext context, SettingsPropertyCollection collection) { var spvc = new SettingsPropertyValueCollection(); foreach (SettingsProperty item in collection) { var sp = new SettingsProperty(item); var spv = new SettingsPropertyValue(item); spv.SerializedValue = _mySettings[item.Name]; spv.PropertyValue = _mySettings[item.Name]; spvc.Add(spv); } return spvc; }
Как вы можете видеть в коде, для этого вам нужно знать имя параметра, как оно было добавлено в app.config
и Settings.settings
когда вы добавили ссылку на веб-сервис (ConsoleApplication1_net_webservicex_www_BarCode
):
<applicationSettings>
<ConsoleApplication30.Properties.Settings>
<setting name="ConsoleApplication1_net_webservicex_www_BarCode"
serializeAs="String">
<value>http://www.webservicex.net/genericbarcode.asmx</value>
</setting>
</ConsoleApplication30.Properties.Settings>
</applicationSettings>
Это очень простой пример, но вы можете использовать более сложный объект для хранения информации о конфигурации в сочетании с другими свойствами, доступными в контексте, такими как item.Attributes
или же context
для того, чтобы получить правильное значение конфигурации.