在我们的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属性标示。
源码:

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;
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
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);
