在我们的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>     
    
</Student> 
  
</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 
        { 
getset; } 

        [XmlAttribute(
"Age")] 
        
public int Age 
        { 
            
get
            
set
        } 
    } 

    [XmlRoot(
"Class")] 
    
public class Class 
    { 
        [XmlAttribute(
"ClassID")] 
        
public int ClassID 
        { 
            
get
            
set
        } 

        [XmlArray()] 
        [XmlArrayItem(
"Students")] 
        
public System.Collections.Generic.List<Student> Students 
        { 
            
get
            
set
        } 
    } 
}

最后需要说明的是:在于我们的项目中可能存在xml文件还没有加载,的情况,所以加入了时间支持和IsLoaded属性标示。

源码:

  1. View Code   
  2.  
  3. using System;   
  4. using System.Net;   
  5. using System.Windows;   
  6. using System.Windows.Controls;   
  7. using System.Windows.Documents;   
  8. using System.Windows.Ink;   
  9. using System.Windows.Input;   
  10. using System.Windows.Media;   
  11. using System.Windows.Media.Animation;   
  12. using System.Windows.Shapes;   
  13. using System.Xml;   
  14. using System.Xml.Linq;   
  15. using System.Linq;   
  16. using System.Collections.Generic;   
  17. using Green.Utility.Utils;   
  18.  
  19. namespace SilverlightApplication2   
  20. {   
  21.     public delegate void LoadComplete();   
  22.  
  23.     public class SLConfigManager   
  24.     {   
  25.         private XDocument document = null;   
  26.  
  27.         private static readonly SLConfigManager _SLConfigManager = new SLConfigManager();   
  28.         private Dictionary<string, object> dict = new Dictionary<string, object>();   
  29.         private Dictionary<string, string> appSettings = new Dictionary<string, string>();   
  30.         private string _ConfigPath = null;   
  31.  
  32.         public static SLConfigManager Current   
  33.         {   
  34.             get   
  35.             {   
  36.                 return _SLConfigManager;   
  37.             }   
  38.         }   
  39.  
  40.         public string ConfigPath   
  41.         {   
  42.             get { return _ConfigPath; }   
  43.             set   
  44.             {   
  45.                 if (_ConfigPath != value)   
  46.                 {   
  47.                     _ConfigPath = value;   
  48.                     LoadResource();   
  49.                 }   
  50.             }   
  51.         }   
  52.  
  53.         public bool IsLoaded   
  54.         {   
  55.             get;   
  56.             private set;   
  57.         }   
  58.         public event LoadComplete LoadComplete;   
  59.  
  60.         public void EnsureLoadResource()   
  61.         {   
  62.  
  63.             if (document == null)   
  64.             {   
  65.                 LoadResource();   
  66.             }   
  67.         }   
  68.  
  69.         protected virtual void LoadResource()   
  70.         {   
  71.             if (string.IsNullOrEmpty(ConfigPath))   
  72.             {   
  73.                 throw new Exception("ConfigPath is required!");   
  74.             }   
  75.  
  76.             dict.Clear();   
  77.             Uri url = new Uri(Application.Current.Host.Source, ConfigPath);   
  78.             WebClient client = new WebClient();   
  79.             client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);   
  80.             client.OpenReadAsync(url, client);   
  81.         }   
  82.  
  83.         protected virtual void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)   
  84.         {   
  85.             if (e.Error != null)   
  86.             {   
  87.                 throw e.Error;   
  88.             }   
  89.  
  90.             var sw = new System.IO.StreamReader(e.Result);   
  91.             var xml = sw.ReadToEnd();   
  92.             document = XDocument.Parse(xml);   
  93.             sw.Close();   
  94.             e.Result.Close();   
  95.             sw = null;   
  96.  
  97.             GetappSettings();   
  98.  
  99.             IsLoaded = true;   
  100.             if (LoadComplete != null)   
  101.             {   
  102.                 LoadComplete();   
  103.             }   
  104.         }   
  105.  
  106.         protected virtual void GetappSettings()   
  107.         {   
  108.             if (document != null)   
  109.             {   
  110.                 var appSettingsel = document.Root.Element("appSettings");   
  111.                 if (appSettings != null)   
  112.                 {   
  113.                     appSettingsel.Elements("add").ToList().ForEach(e =>   
  114.                     {   
  115.                         var key = e.Attribute("key").Value;   
  116.                         var value = e.Attribute("value").Value;   
  117.                         if (!string.IsNullOrEmpty(key)&&!this.appSettings.ContainsKey(key))   
  118.                         {   
  119.                             this.appSettings.Add(key, value);   
  120.                         }   
  121.                     });   
  122.                 }   
  123.             }   
  124.         }   
  125.  
  126.         public T GetSection<T>(string sectionwhere T : class ,new()   
  127.         {   
  128.             if (document == null)   
  129.             {   
  130.                 // throw new Exception("Config Document is null!");                  
  131.             }   
  132.             if (!dict.ContainsKey(section))   
  133.             {   
  134.                 var el = document.Root.Descendants().SingleOrDefault(t => t.Name == section);   
  135.                 var xml = el.ToString();   
  136.                 dict.Add(section, XmlSerializer<T>(xml));   
  137.             }   
  138.             return dict[sectionas T;   
  139.         }   
  140.  
  141.         protected virtual T XmlSerializer<T>(string xml) where T : class ,new()   
  142.         {   
  143.             System.Xml.Serialization.XmlSerializer serialzer = new System.Xml.Serialization.XmlSerializer(typeof(T));   
  144.             System.IO.MemoryStream ms = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(xml));   
  145.             var obj = serialzer.Deserialize(ms) as T;   
  146.             ms.Flush();   
  147.             ms.Close();   
  148.             ms = null;   
  149.             return obj;   
  150.         }   
  151.  
  152.         public T GetAppSettings<T>(string keywhere T : IConvertible   
  153.         {   
  154.             if (appSettings.ContainsKey(key))   
  155.             {   
  156.                 var val = this.appSettings[key];   
  157.                 if (string.IsNullOrEmpty(val))   
  158.                     return default(T);   
  159.                 if (typeof(T).IsEnum)   
  160.                 {   
  161.                     return (T)Enum.Parse(typeof(T), val, true);   
  162.                 }   
  163.                 return (T)Convert.ChangeType(val, typeof(T), null);   
  164.             }   
  165.             return default(T);   
  166.         }   
  167.  
  168.         public string GetAppSettings(string key)   
  169.         {   
  170.             return GetAppSettings<string>(key);   
  171.         }   
  172.     }   
  173. }  
  174. 复制代码