Хорошо, это имеет смысл, вы использовали XmlDocument
для десериализации.Просто используйте String
(или любой потоковый ридер, например, @Seb , на который уже указано ), и он будет работать:
public static class Utils
{
public static string SerializeToString(this object instance)
{
if (instance == null)
throw new ArgumentNullException("instance");
StringBuilder sb = new StringBuilder();
XmlSerializer serializer = new XmlSerializer(instance.GetType());
using (StringWriter sw = new StringWriter(sb))
{
serializer.Serialize(sw, instance);
}
return sb.ToString();
}
public static T Deserialize<T>(this string xmlString)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader sr = new StringReader(xmlString))
{
return (T)serializer.Deserialize(sr);
}
}
}
Использование:
// serialize
var xml = filter.SerializeToString();
// deserialize
var cloneFilter = xml.Deserialize<PropertyFilter>();
[Редактировать]
Также, как примечание: никогда не забывайте располагать объекты, реализующие IDisposable
.Вот почему конструкции using
добавляются для любых экземпляров Stream
.
[Edit2]
Как сказал Антон, в этом случае вам нужно указать дополнительные типыявно, потому что XmlSerializer
не ищет все возможные типы, чтобы найти соответствующий класс.
A немного лучшее решение может быть использовать перегрузку XmlSerializer
, которая принимает эти типы (чтобы вам не нужно было вручную добавлять атрибуты):
public static T Deserialize<T>(this string xmlString)
{
Type[] typesToInclude = GetAllPossibleTypes();
XmlSerializer serializer = new XmlSerializer(typeof(T), typesToInclude);
using (StringReader sr = new StringReader(xmlString))
{
return (T)serializer.Deserialize(sr);
}
}
Это можно сделать один раз при запуске приложения, но вам нужно предоставить соответствующую сборку (или несколько сборок), чтобы убедиться, чтопокрыты все возможные типы:
public static class Utils
{
private static readonly Type[] _typesToInclude = GetPossibleUserTypes();
private static Type[] GetPossibleUserTypes()
{
// this part should be changed to load types from the assembly
// that contains your potential Value candidates
Assembly assembly = Assembly.GetAssembly(typeof(PropertyFilter));
// get public classes only
return assembly.GetTypes().Where(t => t.IsPublic && !t.IsAbstract).ToArray();
}
public static string SerializeToString(this object instance)
{
if (instance == null)
throw new ArgumentNullException("instance");
var sb = new StringBuilder();
var serializer = new XmlSerializer(instance.GetType(), _typesToInclude);
using (StringWriter sw = new StringWriter(sb))
{
serializer.Serialize(sw, instance);
}
return sb.ToString();
}
public static T Deserialize<T>(this string xmlString)
{
var serializer = new XmlSerializer(typeof(T), _typesToInclude);
using (StringReader sr = new StringReader(xmlString))
{
return (T)serializer.Deserialize(sr);
}
}
}