我有几个扩展方法来处理我的类的序列化,因为这可能是一个耗时的过程,所以它们为每个类创建一次,并通过此方法分发.
I have a couple extension methods that handle serialization of my classes, and since it can be a time consuming process, they are created once per class, and handed out by this method.
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()调用的
This is called by the extension method .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/")
属性.
Unfortunately, when Serializing classes that are auto-generated, they have the attribute XmlTypeAttribute(Namespace="http://tempuri.org/")
applied to them.
这会导致非自动生成的对应项的反序列化失败.
This causes the deserialization by the the non-auto-generated counterparts to fail.
我需要序列化程序完全忽略并且不应用命名空间,但是我在第一块代码中编写的内容似乎并没有删除它,我仍然以这样的 xml 结束
I need the serializer to completely ignore and not apply the namespace, but what I have written in the first block of code doesn't seem to remove it, I still end up with xml like this
<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/"
属性.
Instead of the same, minus the xmlns="http://tempuri.org/"
attribute.
请帮忙,谢谢,这快把我逼疯了!
Please help, thanks, this is driving me crazy!
我知道问题所在,只是不知道如何解决.
I know the problem, just not how to fix it.
我的课,不仅仅是简单的类型.
My class, isn't just full of simple types.
它包含具有其他类类型的属性.它们也是使用 XmlTypeAttribute(Namespace = "http://tempuri.org/")
属性自动生成的.所以发生的事情是,当序列化发生时,它序列化了我的类的属性,它们没有经过我的自定义序列化,因此应用了属性而不是覆盖了属性.
It contains properties with types of other classes. Which are also auto-generated with the XmlTypeAttribute(Namespace = "http://tempuri.org/")
attribute. So what is happening, is that when serialization occurs, and it serializes the properties of my class, they aren't going through my custom serialization, and thus, are having the attribute applied and not overridden.
现在我只需要弄清楚如何跳那个箍.有什么想法吗?
Now I just need to figure out how to jump that hoop. Any thoughts as to how?
编辑 2:
以下可以在没有 xmlns 的情况下进行序列化...但是我在反序列化端遇到了问题,只是不确定它是否相关
The following works to serialize WITHOUT xmlns... but I'm having a problem on the deserialization end, just not yet sure if it's related or not
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];
}
最终使用来自的解决方案如何使用 C# 从 XML 中删除所有命名空间?
Ended up using solution from 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)));
}
没问题 - 只需将一个空字符串作为默认命名空间传递给 XML 序列化程序即可:
No problem - just pass an empty string as the default namespace to the XML serializer:
XmlSerializer newSerializer =
new XmlSerializer(typeOfT, "");
不幸的是,如果您确实需要定义 XmlAttributeOverrides
和默认命名空间,则没有简单的构造函数重载 - 所以您可以跳过 XmlAttributeOverrides
并使用我提到的构造函数,或者您需要使用定义所有可能参数的参数(包括 XmlAttributeOverrides 和默认 XML 命名空间 - 以及更多).
Unfortunately, there's no easy constructor overload if you really need to define the XmlAttributeOverrides
and the default namespace - so either you can skip the XmlAttributeOverrides
and use that constructor I mentioned, or you need to use the one that defines all possible parameters (including XmlAttributeOverrides and default XML namespaces - and a few more).
这篇关于没有 xmlns 的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!