【WP8】自定义配置存储类
之前在WP7升级到WP8的时候遇到配置不兼容的问题
情景:之前只有一个WP7版本,现在需要发布WP8版本,让用户可以从原来的WP7版本升级到WP8版本
一般情况下从WP7升级到WP8没什么问题
但是在项目中升级到WP8的时候,原先在WP7下保存在IsolatedStorageSettings的数据都不出来,经过调试发现
1、IsolatedStorageSettings存放数据的隔离存储控件的"__ApplicationSettings"文件中,存放的格式如下 {"test":"TestData"}
<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<KeyValueOfstringanyType>
<Key>test</Key>
<Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">TestData</Value>
</KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType>
2、但是原来的项目中使用了友盟WP7版本,后来的项目中使用的是WP8版本,友盟会向"__ApplicationSettings"文件中写入数据,如下:
UmengSDK.Business.OnlineConfigManager+OnlineConfig, UmengAnalyticsWP7, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null
<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<KeyValueOfstringanyType>
<Key>test</Key>
<Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">TestData</Value>
</KeyValueOfstringanyType>
<KeyValueOfstringanyType>
<Key>device_id</Key>
<Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">0BBB2DF41DD5688A25517F2968339DC0</Value>
</KeyValueOfstringanyType>
<KeyValueOfstringanyType>
<Key>wp_device</Key>
<Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">1C43AC07795C55C2ADA78B0DD5A79B3660A7D137</Value>
</KeyValueOfstringanyType>
<KeyValueOfstringanyType>
<Key>config</Key>
<Value xmlns:d3p1="http://schemas.datacontract.org/2004/07/UmengSDK.Business" i:type="d3p1:OnlineConfigManager.OnlineConfig">
<d3p1:Interval>30</d3p1:Interval>
<d3p1:LastConfigTime>Wed Jul 02 00:43:35 CST 2014</d3p1:LastConfigTime>
<d3p1:Policy>BATCH_AT_LAUNCH</d3p1:Policy>
</Value>
</KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType>
3、而上面数据到了WP8上就不能正常读取原来存放的数据(如果在WP8项目中用WP7版的友盟则可以正常读取),导致原来存放的其他信息也读取不出来
4、下面试图自定义一个与 IsolatedStorageSettings 功能类似的类用于小数据的存取,避免第三方类库对"__ApplicationSettings"文件的修改导致一些兼容性问题
IsolatedStorageSettings 存放的是键值对,也就是字典模型,我们需要把Dictionary序列化到文件中,但是Dictionary不支持直接序列化,先对Dictionary进行扩展,让其支持序列化
using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization; namespace XTuOne.Common.Helpers
{
/// <summary>
/// 可序列化的Dictionary
/// </summary>
[XmlRoot("Dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
#region 构造函数,调用基类的构造函数 public SerializableDictionary()
{
} public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
: base(dictionary)
{
} public SerializableDictionary(IEqualityComparer<TKey> comparer)
: base(comparer)
{
} public SerializableDictionary(int capacity)
: base(capacity)
{
} public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
: base(capacity, comparer)
{
} public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
: base(dictionary, comparer)
{
} #endregion #region IXmlSerializable 接口的实现 public XmlSchema GetSchema()
{
throw new NotImplementedException();
} /// <summary>
/// 从对象的XML表示形式生成该对象
/// </summary>
/// <param name="reader"></param>
public void ReadXml(XmlReader reader)
{
var keySerializer = new XmlSerializer(typeof (TKey));
var valueSerializer = new XmlSerializer(typeof (TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read(); if (wasEmpty)
return;
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.ReadStartElement("Key");
TKey key = (TKey) keySerializer.Deserialize(reader);
reader.ReadEndElement(); reader.ReadStartElement("Value");
TValue value = (TValue) valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.MoveToContent();
}
reader.ReadEndElement();
} /// <summary>
/// 将对象转换为其XML表示形式
/// </summary>
/// <param name="writer"></param>
public void WriteXml(XmlWriter writer)
{
var keySerializer = new XmlSerializer(typeof (TKey));
var valueSerializer = new XmlSerializer(typeof (TValue));
foreach (TKey key in this.Keys)
{
writer.WriteStartElement("Key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement(); writer.WriteStartElement("Value");
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
}
} #endregion
}
}
5、使用系统的Xml序列化功能保存数据
using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Xml.Linq;
using System.Xml.Serialization; namespace XTuOne.Common.Helpers
{
public class XmlHelper
{
private XmlHelper()
{
} /// <summary>
/// 序列化对象到文件
/// </summary>
/// <param name="file">文件路径:"/test.xml"</param>
/// <param name="obj"></param>
public static void Serialize<T>(string file, T obj)
{
using (var sf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var fs = new IsolatedStorageFileStream(file, FileMode.OpenOrCreate, FileAccess.Write, sf))
{
var serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(fs, obj);
}
}
} /// <summary>
/// 反序列化文件到对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="file">文件路径:"/test.xml"</param>
public static T Deserialize<T>(string file)
{
using (var sf = IsolatedStorageFile.GetUserStoreForApplication())
{
var serializer = new XmlSerializer(typeof(T));
using (var fs = sf.OpenFile(file, FileMode.Open, FileAccess.Read))
{
return (T)serializer.Deserialize(fs);
}
}
} /// <summary>
/// 读取配置文件的信息
/// </summary>
/// <param name="file">前面不加/</param>
/// <param name="node">用.隔开(例如App.Version)</param>
/// <param name="attribute"></param>
public static string GetConfigValue(string file,string node, string attribute)
{
var configFile = Application.GetResourceStream(new Uri(file, UriKind.Relative));
return GetXmlValue(configFile.Stream, node, attribute);
} private static string GetXmlValue(Stream stream, string node, string attribute)
{
var configDoc = XDocument.Load(stream);
XElement temp = null;
foreach (var n in node.Split('.'))
{
if (temp == null)
{
temp = configDoc.Element(n);
continue;
}
temp = temp.Element(n);
} if (temp == null)
{
throw new NullReferenceException();
}
return temp.Attribute(attribute).Value;
} }
}
XmlHelper
// *************************************************
//
// 作者:bomo
// 小组:WP开发组
// 创建日期:2014/6/21 14:55:56
// 版本号:V1.00
// 说明:
//
// *************************************************
//
// 修改历史:
// Date WhoChanges Made
// 2014/6/21 14:55:56 bomo Initial creation
//
// ************************************************* using System.IO;
using System.IO.IsolatedStorage;
using XTuOne.Common.Helpers; namespace XTuOne.Utility.Helpers
{
/// <summary>
/// 自定义应用程序配置(相当于IsolatedStorageSetting)
/// </summary>
public class ApplicationSetting
{
/// <summary>
/// 保存配置的文件名
/// </summary>
private readonly string filePath; private readonly SerializableDictionary<string, object> dictionary; public ApplicationSetting(string filePath)
{
this.filePath = filePath;
//读取配置
using (var sf = IsolatedStorageFile.GetUserStoreForApplication())
{
var directory = Path.GetDirectoryName(filePath);
if (directory != null)
{
if (sf.DirectoryExists(directory))
{
sf.CreateDirectory(directory);
}
} dictionary = sf.FileExists(filePath)
? XmlHelper.Deserialize<SerializableDictionary<string, object>>(filePath)
: new SerializableDictionary<string, object>();
}
} /// <summary>
/// 通过索引赋值需要显式保存
/// </summary>
public object this[string key]
{
get { return Contains(key) ? dictionary[key] : null; }
set { dictionary[key] = value.ToString(); }
} public T Get<T>(string key)
{
return (T) dictionary[key];
} /// <summary>
/// 通过键获取值,如果不存在,则返回传入的默认值
/// </summary>
public T Get<T>(string key, T defaultValue)
{
return dictionary.ContainsKey(key) ? (T) dictionary[key] : defaultValue;
} /// <summary>
/// 设置值,自动保存
/// </summary>
public void Set(string key, object value)
{
if (dictionary.ContainsKey(key))
{
dictionary[key] = value;
}
else
{
dictionary.Add(key, value);
}
Save();
} /// <summary>
/// 保存配置到文件
/// </summary>
public void Save()
{
XmlHelper.Serialize(filePath, dictionary);
} /// <summary>
/// 判断是否包含键
/// </summary>
public bool Contains(string key)
{
return dictionary.ContainsKey(key);
} /// <summary>
/// 析构时保存数据
/// </summary>
~ApplicationSetting()
{
Save();
}
}
}
使用自定义的配置管理器可以控制文件信息,不会出现上述与第三方类库的一些兼容性问题(当然,这种情况比较少)
注意:该配置文件只支持基础类型,不支持复杂类型
【WP8】自定义配置存储类的更多相关文章
- spring-boot 速成(4) 自定义配置
spring-boot 提供了很多默认的配置项,但是开发过程中,总会有一些业务自己的配置项,下面示例了,如何添加一个自定义的配置: 一.写一个自定义配置的类 package com.example.c ...
- .Net 配置文件--继承ConfigurationSection实现自定义处理类处理自定义配置节点
除了使用继承IConfigurationSectionHandler的方法定义处理自定义节点的类,还可以通过继承ConfigurationSection类实现同样效果. 首先说下.Net配置文件中一个 ...
- .Net 配置文件——继承ConfigurationSection实现自定义处理类处理自定义配置节点
除了使用继承IConfigurationSectionHandler的方法定义处理自定义节点的类,还可以通过继承ConfigurationSection类实现同样效果. 首先说下.Net配置文件中一个 ...
- 利用NSUserdefaults来存储自定义的NSObject类及自定义类数组
利用NSUserdefaults来存储自定义的NSObject类及自定义类数组 1.利用NSUserdefaults来存储自定义的NSObject类 利用NSUserdefaults也可以来存储及获取 ...
- Spring 自定义配置类bean
<!-- 引入配置文件 --> <bean id="propertyConfigurer" class="org.springframework.bea ...
- 【spring boot】7.静态资源和拦截器处理 以及继承WebMvcConfigurerAdapter类进行更多自定义配置
开头是鸡蛋,后面全靠编!!! ======================================================== 1.默认静态资源映射路径以及优先顺序 Spring B ...
- C#如何使用和开发自定义配置节
在日常的程序设计中,如何灵活和巧妙地运用配置信息是一个成功的设计师的首要选择.这不仅是为了程序设计得更灵活性和可扩展性,也是为了让你的代码给人以清新的感觉.程序中的配置信息一般放在应用程序的app.c ...
- App.config和Web.config配置文件的自定义配置节点
前言 昨天修改代码发现了一个问题,由于自己要在WCF服务接口中添加了一个方法,那么在相应调用的地方进行更新服务就可以了,不料意外发生了,竟然无法更新.左查右查终于发现了问题.App.config配置文 ...
- rancher2.1.7安装nfs 存储类
NFS存储类不建议作大规模存储,块存储建议采用CEPH(独立安装) NFS只作为外接存储与普通NGINX类的配置文件,业务配置文件建议走配置中心. 增加自定义商店 地址为:https://github ...
随机推荐
- [转]MySQL update join语句
原文地址:https://www.jianshu.com/p/f99665266bb1 在本教程中,您将学习如何使用MySQL UPDATE JOIN语句来执行跨表更新.我们将逐步介绍如何使用INNE ...
- Sql server在另一台服务器,在Visual Studio 中没问题,IIS中 提示“在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。。。。”
可能问题一: 确切的说是在IIS 7.5中有这问题 就是在visual studio中都用的好好的,但是加载到IIS上的时候竟然报错“ 在与 SQL Server 建立连接时出现与网络相关的或特定于实 ...
- <[长期赢利:股票价值投资方法]>读书笔记
书在这里 风险是因为不够专业 在股市里,要不断拓宽自己的眼界 投资如长跑,贵在坚持 长线为主,短线为辅:重视选股,减少盲目:耐心等待,春天回来 除了要与银行利息比以外,还要了解当时股票的平均市盈率,再 ...
- shell常用命令大全
目录: 一.文件目录类命令 二.文件压缩和归档类命令 三.系统状态类命令 四.网络类命令 五.其他 一.文件目录类命令 1.查看联机帮助信息. man命令.#man ls info命令. #info ...
- STM32 ADC多通道转换
描述:用ADC连续采集11路模拟信号,并由DMA传输到内存.ADC配置为扫描并且连续转换模式,ADC的时钟配置为12MHZ.在每次转换结束后,由DMA循环将转换的数据传输到内存中.ADC可以连续采集N ...
- ML-DL-各种资源汇总
1.Used Libraries, Datasets, and Models 1.1 Libraries TensorFlow (from Google): https://www.tensorflo ...
- sqoop 常见错误以及处理方式
Oracle: Connection Reset Errors 错误代码 // :: INFO mapred.JobClient: Task Id : attempt_201105261333_000 ...
- WebRTC 源码分析(五):安卓 P2P 连接过程和 DataChannel 使用
从本篇起,我们将迈入新的领域:网络传输.首先我们看看 P2P 连接的建立过程,以及 DataChannel 的使用,最终我们会利用 DataChannel 实现一个 P2P 的文字聊天功能. P2P ...
- Java设计模式(1)工厂模式(Factory模式)
工厂模式定义:提供创建对象的接口. 为何使用工厂模式 工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见. 为什么工厂模式是如此常用?因 ...
- Android studio 3+版本apk安装失败问题
studio2.3升级到3.1之后将apk发给别人下载到手机上安装,华为提示安装包无效或与操作系统不兼容,魅族提示apk仅为测试版,要求下载正式版安装. 在网上找了一下,发现是studio3.0之后的 ...