问题
We are working on a legacy C# enterprise app. Its client uses several web services, whose URLs, among lots of other settings, are read from the local app.config file. We want to migrate these settings into a global DB to simplify their management. However, I can't figure out how (and whether) it is possible to migrate the web service URLs. These are read from the service client code generated by VS and I can't seem to find a way to tell VS to use a different settings provider than the one generated into Settings.Designer.cs
.
We can overwrite the service facade's Url
property with the value we want, after it is created - this is the solution currently used in several places in the code. However, I wouldn't like to touch every part of our codebase where any of these services is used (now and in the future). Even less would I like to modify generated code.
There has to be a better, cleaner, safer solution - or is there?
Btw our app runs on .NET 2.0 and we won't migrate to newer versions of the platform in the foreseeable future.
回答1:
The Refernce.cs
file that is generated by the Visual Studio indicates that the URL of the webservice will be retrieved from the settings:
this.Url = global::ConsoleApplication1.Properties.
Settings.Default.ConsoleApplication1_net_webservicex_www_BarCode;
I believe that John Saunders gave you a wonderful suggestion in his comment. You need a SettingsProvider class which:
...defines the mechanism for storing configuration data used in the application settings architecture. The .NET Framework contains a single default settings provider, LocalFileSettingsProvider, which stores configuration data to the local file system. However, you can create alternate storage mechanisms by deriving from the abstract SettingsProvider class. The provider that a wrapper class uses is determined by decorating the wrapper class with the SettingsProviderAttribute. If this attribute is not provided, the default, LocalFileSettingsProvider, is used.
I don't know how much you have progressed following this approach, but it should go pretty straighforward:
Create the
SettingsProvider
class: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 } }
Extend the class definition for the project's
YourProjectName.Properties.Settings
partial class and decorate it with theSettingsProviderAttribute
:[System.Configuration.SettingsProvider(typeof(MySettings.Providers.MySettingsProvider))] internal sealed partial class Settings { // }
In the overridden
GetPropertyValues
method, you have to get the mapped value from the_mySettings
dictionary: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; }
As you can see in the code, in order to do that, you need to know the setting name as it was added in the app.config
and the Settings.settings
when you have added the reference to the web service (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>
This is a very simple example, but you might use a more complex object to store the configuration information in conjunction with other properties available in the context such as item.Attributes
or context
in order to get the proper configuration value.
来源:https://stackoverflow.com/questions/14651604/how-to-configure-asmx-web-service-url-from-remote-source