在我們的silverlight項目中,是被打包為xap zip檔案下載下傳到用戶端,是以silverlight中的app配置檔案我們不能直接修改,而在其宿主web host中的web.config在服務端我們也不能直接通路。在我們的項目中遇見了這個問題是以我就有了此部落格。
先說明解決這個問題的方案有:
1:調用wcf,webservice,Asp.net頁面等服務端資料源,異步顯示在我們的UI。
2:利用silverlight項目的宿首頁面 object,傳入初始化參數,在silverlight app中擷取。
上面的方案都是針對于我們的少量有限配置資訊的擷取。我這裡做的是利用在服務端的xml配置檔案來模拟配置檔案(為什麼不用web.config?以為存在權限資訊的問題,是以我覺得盡量避免此檔案資訊暴露)。在silverlight的異步加載xml文檔并解析xml文檔。形成配置資訊。
為了全局使用,早些加載xml文檔,我們需要在app中加一句:
SLConfigManager.Current.ConfigPath = "../SlConfig.xml";//配置檔案的路徑,相對于我們的xap檔案路徑。
我們先看一下測試xml:
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<appSettings>
<add key="test1" value="123"></add>
<add key="test2" value="1"></add>
</appSettings>
<Class ClassID="111">
<Student Age="123">
<Name>ddddd</Name>
</Student>
<Student Age="28">
<Name>111</Name>
</Class>
</Configuration
>
這是我們可以使用:
void Page1_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show(SLConfigManager.Current.GetSection<Class>("Class").ClassID + "");
MessageBox.Show(SLConfigManager.Current.GetAppSettings("test1").ToString());
MessageBox.Show(SLConfigManager.Current.GetAppSettings<Sex>("test2").ToString());
}
public enum Sex
man,woman
}
在這裡我們模拟了AppSettings,和Section(注:這裡的section,不需要預申明,在利用xml轉化形成的,更利于我們的配置擴充性,使用到了XmlRoot,XmlElement等attribute),在看看我們的Class類:
using System.Xml.Serialization;
namespace SilverlightApplication2
{
[XmlRoot("Student")]
public class Student
{
[XmlElement("Name")]
public string Name
{ get; set; }
[XmlAttribute("Age")]
public int Age
{
get;
set;
}
}
[XmlRoot("Class")]
public class Class
[XmlAttribute("ClassID")]
public int ClassID
[XmlArray()]
[XmlArrayItem("Students")]
public System.Collections.Generic.List<Student> Students
}
最後需要說明的是:在于我們的項目中可能存在xml檔案還沒有加載,的情況,是以加入了時間支援和IsLoaded屬性标示。
源碼:
View Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Linq;
using System.Linq;
using System.Collections.Generic;
using Green.Utility.Utils;
namespace SilverlightApplication2
{
public delegate void LoadComplete();
public class SLConfigManager
{
private XDocument document = null;
private static readonly SLConfigManager _SLConfigManager = new SLConfigManager();
private Dictionary<string, object> dict = new Dictionary<string, object>();
private Dictionary<string, string> appSettings = new Dictionary<string, string>();
private string _ConfigPath = null;
public static SLConfigManager Current
{
get
{
return _SLConfigManager;
}
}
public string ConfigPath
get { return _ConfigPath; }
set
if (_ConfigPath != value)
{
_ConfigPath = value;
LoadResource();
}
public bool IsLoaded
get;
private set;
public event LoadComplete LoadComplete;
public void EnsureLoadResource()
if (document == null)
LoadResource();
protected virtual void LoadResource()
if (string.IsNullOrEmpty(ConfigPath))
throw new Exception("ConfigPath is required!");
dict.Clear();
Uri url = new Uri(Application.Current.Host.Source, ConfigPath);
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(url, client);
protected virtual void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
if (e.Error != null)
throw e.Error;
var sw = new System.IO.StreamReader(e.Result);
var xml = sw.ReadToEnd();
document = XDocument.Parse(xml);
sw.Close();
e.Result.Close();
sw = null;
GetappSettings();
IsLoaded = true;
if (LoadComplete != null)
LoadComplete();
protected virtual void GetappSettings()
if (document != null)
var appSettingsel = document.Root.Element("appSettings");
if (appSettings != null)
appSettingsel.Elements("add").ToList().ForEach(e =>
{
var key = e.Attribute("key").Value;
var value = e.Attribute("value").Value;
if (!string.IsNullOrEmpty(key)&&!this.appSettings.ContainsKey(key))
{
this.appSettings.Add(key, value);
}
});
public T GetSection<T>(string section) where T : class ,new()
// throw new Exception("Config Document is null!");
if (!dict.ContainsKey(section))
var el = document.Root.Descendants().SingleOrDefault(t => t.Name == section);
var xml = el.ToString();
dict.Add(section, XmlSerializer<T>(xml));
return dict[section] as T;
protected virtual T XmlSerializer<T>(string xml) where T : class ,new()
System.Xml.Serialization.XmlSerializer serialzer = new System.Xml.Serialization.XmlSerializer(typeof(T));
System.IO.MemoryStream ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(xml));
var obj = serialzer.Deserialize(ms) as T;
ms.Flush();
ms.Close();
ms = null;
return obj;
public T GetAppSettings<T>(string key) where T : IConvertible
if (appSettings.ContainsKey(key))
var val = this.appSettings[key];
if (string.IsNullOrEmpty(val))
return default(T);
if (typeof(T).IsEnum)
return (T)Enum.Parse(typeof(T), val, true);
return (T)Convert.ChangeType(val, typeof(T), null);
return default(T);
public string GetAppSettings(string key)
return GetAppSettings<string>(key);
}
}
複制代碼
本文轉自 破狼 51CTO部落格,原文連結:http://blog.51cto.com/whitewolfblog/835166,如需轉載請自行聯系原作者