【发布时间】:2010-06-22 15:10:17
【问题描述】:
我有几个扩展方法来处理我的类的序列化,因为这可能是一个耗时的过程,所以它们为每个类创建一次,并通过这个方法分发。
public static XmlSerializer GetSerializerFor(Type typeOfT)
{
if (!serializers.ContainsKey(typeOfT))
{
var xmlAttributes = new XmlAttributes();
var xmlAttributeOverrides = new XmlAttributeOverrides();
System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT));
xmlAttributes.Xmlns = false;
xmlAttributeOverrides.Add(typeOfT, xmlAttributes);
var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides);
serializers.Add(typeOfT, newSerializer);
}
return serializers[typeOfT];
}
这是由扩展方法.Serialize()调用的
public static XElement Serialize(this object source)
{
try
{
var serializer = XmlSerializerFactory.GetSerializerFor(source.GetType());
var xdoc = new XDocument();
using (var writer = xdoc.CreateWriter())
{
serializer.Serialize(writer, source, new XmlSerializerNamespaces(new[] { new XmlQualifiedName("", "") }));
}
return (xdoc.Document != null) ? xdoc.Document.Root : new XElement("Error", "Document Missing");
}
catch (Exception x)
{
return new XElement("Error", x.ToString());
}
}
不幸的是,在对自动生成的类进行序列化时,它们应用了 XmlTypeAttribute(Namespace="http://tempuri.org/") 属性。
这会导致非自动生成的对应对象的反序列化失败。
我需要序列化程序完全忽略并且不应用命名空间,但我在第一块代码中编写的内容似乎并没有删除它,我仍然以这样的 xml 结束
<Note>
<ID xmlns="http://tempuri.org/">12</ID>
<Author xmlns="http://tempuri.org/">
<ID>1234</ID>
<Type>Associate</Type>
<IsAvailable>false</IsAvailable>
</Author>
<Created xmlns="http://tempuri.org/">2010-06-22T09:38:01.5024351-05:00</Created>
<Text xmlns="http://tempuri.org/">This is an update</Text>
</Note>
而不是相同,减去xmlns="http://tempuri.org/" 属性。
请帮忙,谢谢,这快把我逼疯了!
编辑:
我知道问题所在,只是不知道如何解决。
我的课,不仅仅是简单的类型。
它包含具有其他类类型的属性。它们也是使用 XmlTypeAttribute(Namespace = "http://tempuri.org/") 属性自动生成的。所以发生的事情是,当序列化发生时,它序列化我的类的属性,它们没有经过我的自定义序列化,因此,应用了属性并且没有被覆盖。
现在我只需要弄清楚如何跳那个箍。有什么想法吗?
编辑 2:
以下可以在没有 xmlns 的情况下进行序列化...但是我在反序列化端遇到了问题,只是不确定它是否相关
public static XmlSerializer GetSerializerFor(Type typeOfT)
{
if (!serializers.ContainsKey(typeOfT))
{
var xmlAttributes = new XmlAttributes();
var xmlAttributeOverrides = new XmlAttributeOverrides();
System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT));
xmlAttributes.XmlType = new XmlTypeAttribute
{
Namespace = ""
};
xmlAttributes.Xmlns = false;
var types = new List<Type> {typeOfT, typeOfT.BaseType};
foreach (var property in typeOfT.GetProperties())
{
types.Add(property.PropertyType);
}
types.RemoveAll(t => t.ToString().StartsWith("System."));
foreach (var type in types)
{
xmlAttributeOverrides.Add(type, xmlAttributes);
}
var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides);
//var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides, extraTypes.ToArray(), new XmlRootAttribute(), string.Empty);
//var newSerializer = new XmlSerializer(typeOfT, string.Empty);
serializers.Add(typeOfT, newSerializer);
}
return serializers[typeOfT];
}
编辑3: 最终使用来自的解决方案 How to remove all namespaces from XML with C#?
public static XElement RemoveAllNamespaces(this XElement source)
{
return !source.HasElements
? new XElement(source.Name.LocalName)
{
Value = source.Value
}
: new XElement(source.Name.LocalName, source.Elements().Select(el => RemoveAllNamespaces(el)));
}
【问题讨论】:
-
你的最后一个解决方案应该被命名为
RemoveAllAttributes
标签: c# xml-serialization namespaces