之前在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】自定义配置存储类的更多相关文章

  1. spring-boot 速成(4) 自定义配置

    spring-boot 提供了很多默认的配置项,但是开发过程中,总会有一些业务自己的配置项,下面示例了,如何添加一个自定义的配置: 一.写一个自定义配置的类 package com.example.c ...

  2. .Net 配置文件--继承ConfigurationSection实现自定义处理类处理自定义配置节点

    除了使用继承IConfigurationSectionHandler的方法定义处理自定义节点的类,还可以通过继承ConfigurationSection类实现同样效果. 首先说下.Net配置文件中一个 ...

  3. .Net 配置文件——继承ConfigurationSection实现自定义处理类处理自定义配置节点

    除了使用继承IConfigurationSectionHandler的方法定义处理自定义节点的类,还可以通过继承ConfigurationSection类实现同样效果. 首先说下.Net配置文件中一个 ...

  4. 利用NSUserdefaults来存储自定义的NSObject类及自定义类数组

    利用NSUserdefaults来存储自定义的NSObject类及自定义类数组 1.利用NSUserdefaults来存储自定义的NSObject类 利用NSUserdefaults也可以来存储及获取 ...

  5. Spring 自定义配置类bean

    <!-- 引入配置文件 --> <bean id="propertyConfigurer" class="org.springframework.bea ...

  6. 【spring boot】7.静态资源和拦截器处理 以及继承WebMvcConfigurerAdapter类进行更多自定义配置

    开头是鸡蛋,后面全靠编!!! ========================================================  1.默认静态资源映射路径以及优先顺序 Spring B ...

  7. C#如何使用和开发自定义配置节

    在日常的程序设计中,如何灵活和巧妙地运用配置信息是一个成功的设计师的首要选择.这不仅是为了程序设计得更灵活性和可扩展性,也是为了让你的代码给人以清新的感觉.程序中的配置信息一般放在应用程序的app.c ...

  8. App.config和Web.config配置文件的自定义配置节点

    前言 昨天修改代码发现了一个问题,由于自己要在WCF服务接口中添加了一个方法,那么在相应调用的地方进行更新服务就可以了,不料意外发生了,竟然无法更新.左查右查终于发现了问题.App.config配置文 ...

  9. rancher2.1.7安装nfs 存储类

    NFS存储类不建议作大规模存储,块存储建议采用CEPH(独立安装) NFS只作为外接存储与普通NGINX类的配置文件,业务配置文件建议走配置中心. 增加自定义商店 地址为:https://github ...

随机推荐

  1. docker探索-CentOS7中配置Docker的yum源并升级安装docker1.13(十)

    此处使用的是CentOS7,内核版本为 [root@localhost ~]# uname -r -.el7.x86_64 该版本下,配置了yum的源为阿里的镜像源,具体的配置方法可以参见阿里镜像源配 ...

  2. 最美应用API接口分析

    最美应用API接口分析html, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirror-scr ...

  3. <股市高手和你想的不一样>读书笔记

    书在这里 在股市中挖掘真正有成长潜力的好企业,是成功投资者的关键 股票被低估的时候,才值得买 我们买股票,就是买这家公司的未来 公司的成长性要重点看两个方面,一个方面要看该公司近三年的成长趋势,另外一 ...

  4. c++--------获取某个路径下所有文件的文件名,读写TXT文件到新的文件

    好久没写io操作了,手生了好多,为了防止自己老年痴呆,最简单实用的c++代码也push上来吧, 环境:mac,xcode(注意mac环境下Windows的函数不能用) 功能:打开一个文件目录,把所有文 ...

  5. nginx负载均衡和反相代理的配置

    偷懒,参考这里 https://www.cnblogs.com/taiyonghai/p/6728707.html

  6. linux下查看cpu物理个数和逻辑个数

    hadoop@chw-desktop3:~$ cat /proc/cpuinfo processor   : 0 vendor_id   : GenuineIntel cpu family  : 15 ...

  7. [数据结构]最大流之Ford-Fulkerson算法

    本文主要讲解最大流问题的Ford-Fulkerson解法.可以说这是一种方法,而不是算法,因为它包含具有不同运行时间的几种实现.该方法依赖于三种重要思想:残留网络,增广路径和割. 在介绍着三种概念之前 ...

  8. JS学习 - offset家族(一)

    JS学习 - offset家族(一) 先来张图开开胃 offsetWidth offetHeight 得到对象的宽度和高度(自己的,与他人无关) offsetWidth = width + borde ...

  9. minerd

    云服务器 ECS Linux 异常进程 minerd 导致系统 CPU 跑满 问题现象 云服务器 ECS Linux 服务器 CPU 跑满,或者使用服务器越来越慢. 问题原因 使用 top 命令看到有 ...

  10. vim for python

    set encoding=utf8 set paste  编辑模式下的 复制粘贴 set expandtab  貌似是一个 tab 替换成4个空格, 而且当你使用 backspace(删除键), 会自 ...