Tengo un par de métodos de extensión que manejan la serialización de mis clases, y dado que puede ser un proceso lento, se crean una vez por clase y se reparten por este método.Serializar SIN 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.Xmlns = false;
xmlAttributeOverrides.Add(typeOfT, xmlAttributes);
var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides);
serializers.Add(typeOfT, newSerializer);
}
return serializers[typeOfT];
}
Esto es llamado por el método de extensión .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());
}
}
Por desgracia, cuando serialización de clases que son auto-generado, que tienen el atributo XmlTypeAttribute(Namespace="http://tempuri.org/")
que se les aplica.
Esto provoca que la deserialización por parte de las contrapartes no generadas automáticamente falle.
necesito el serializador ignorar por completo y no aplicar el espacio de nombres, pero lo que he escrito en el primer bloque de código no parece que quitarlo, que aún así terminar con XML como esto
<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>
En lugar de lo mismo, menos el atributo xmlns="http://tempuri.org/"
.
Por favor, ayuda, gracias, esto me está volviendo loco!
EDIT:
Sé que el problema, pero no cómo solucionarlo.
Mi clase no solo está llena de tipos simples.
Contiene propiedades con tipos de otras clases. Que también se generan automáticamente con el atributo XmlTypeAttribute(Namespace = "http://tempuri.org/")
. Entonces, lo que está sucediendo es que cuando ocurre la serialización y serializa las propiedades de mi clase, no están pasando por mi serialización personalizada, y por lo tanto, están teniendo el atributo aplicado y no anulado.
Ahora solo necesito descubrir cómo saltar ese aro. ¿Alguna idea de cómo?
EDIT 2:
las siguientes obras para serializar SIN xmlns ... pero estoy teniendo un problema en el extremo deserialización, por el momento no está seguro de si está relacionado o no
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];
}
Edit3 : acabaron utilizando solución de 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)));
}
su última solución debería haber sido nombrado 'RemoveAllAttributes' – redtetrahedron