by Michael Wolf via Michael Wolf on 12/15/2008 1:24:11 PM
A problem I hear rumble up from a lot of .Net developers when picking up Silverlight is, “where is ?” My normal answer is, “If it’s not there, do what Microsoft would do… Make your own.” A perfect example of this would be runtime configuration. With the full CLR, so many of us have become accustomed to using ConfigurationManager that reverting to hard-coding values in the binary pains us. By default, Silverlight embeds the ServiceReferences.ClientConfig for service references into the xap, but usually we would prefer to change our service references in our app.config files from our development deployments to production deployments. To overcome this common problem, we have built our own ConfigurationManager. In the example above, the text is being loaded using the following config file living on the web server <?xml version="1.0" encoding="utf-8" ?> <Configuation> <AppSettings> <Add Key="title" Value="Hello World from configuration manager"></Add> </AppSettings> </Configuation> This allows us to edit the config on the fly, outside of the compiled xap, just as you would do with a WPF app.config. Using Linq we can load this data into our configuration object by extracting the key and value pairs. public static void LoadConfig() { WebClient client = new WebClient(); client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted); client.DownloadStringAsync(new Uri("app.xml", UriKind.Relative)); } public static void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Error!=null) { throw e.Error; } // load the data XDocument config = XDocument.Parse(e.Result); var appsettings = from x in config.Descendants("AppSettings").Descendants("Add") select new AppSettings { Key = (string)x.Attribute("Key"), Value = x.Attribute("Value").Value }; _appSettings = new Dictionary(); // add to collection if (appsettings.Count() > 0) { foreach (AppSettings y in appsettings) { _appSettings[y.Key] = y.Value; } } // notify that its available if (ConfigurationAvailable != null) ConfigurationAvailable(null, new EventArgs()); } Then we can access our configuration values in Silverlight just as we would with the .Net CLR-supplied ConfigurationManager. void Page_Loaded(object sender, RoutedEventArgs e) { lblHelloWorld.Text = ConfigurationManager.AppSettings["title"]; } One difference with this approach is that every request with in Silverlight must be asynchronous. So there is a little more startup work to get this wired up nicely. In the demo we show a loading screen first while the app.xml file is loaded, and publish back events letting the Silverlight application know when it’s ready to be used. private void Application_Startup(object sender, StartupEventArgs e) { ConfigurationManager.LoadConfig(); this.RootVisual = new Masterpage(); } void Masterpage_Loaded(object sender, RoutedEventArgs e) { ConfigurationManager.ConfigurationAvailable += new EventHandler(ConfigurationManager_ConfigurationAvailable); LayoutRoot.Children.Add(new Loading()); } Another difference is that, since we are using a file with a .xml extension rather than .config, this file is now publicly available (http://dotnet.cynergysystems.com/silverlight/config/clientbin/app.xml), and thus shouldn’t contain sensitive data. This is more similar to a desktop app.config than a web.config scenario. Yet if you are really concerned about exposing somewhat sensitive data, but you must have the flexibility of the config file, you can always encrypt the xml file using the System.Security.Cryptography libs on both server and client (see last weeks post). email it!bookmark it!digg it!
<?xml version="1.0" encoding="utf-8" ?> <Configuation> <AppSettings> <Add Key="title" Value="Hello World from configuration manager"></Add> </AppSettings> </Configuation>
public static void LoadConfig() { WebClient client = new WebClient(); client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted); client.DownloadStringAsync(new Uri("app.xml", UriKind.Relative)); } public static void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Error!=null) { throw e.Error; } // load the data XDocument config = XDocument.Parse(e.Result); var appsettings = from x in config.Descendants("AppSettings").Descendants("Add") select new AppSettings { Key = (string)x.Attribute("Key"), Value = x.Attribute("Value").Value }; _appSettings = new Dictionary(); // add to collection if (appsettings.Count() > 0) { foreach (AppSettings y in appsettings) { _appSettings[y.Key] = y.Value; } } // notify that its available if (ConfigurationAvailable != null) ConfigurationAvailable(null, new EventArgs()); }
void Page_Loaded(object sender, RoutedEventArgs e) { lblHelloWorld.Text = ConfigurationManager.AppSettings["title"]; }
private void Application_Startup(object sender, StartupEventArgs e) { ConfigurationManager.LoadConfig(); this.RootVisual = new Masterpage(); } void Masterpage_Loaded(object sender, RoutedEventArgs e) { ConfigurationManager.ConfigurationAvailable += new EventHandler(ConfigurationManager_ConfigurationAvailable); LayoutRoot.Children.Add(new Loading()); }
Original Post: Silverlight ConfigurationManager
The content of the postings is owned by the respective author. Silverlight Feeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on Silverlight Feeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.