.net - serialización - Serializar objeto sin espacios de nombres utilizando DataContractSerializer
serializar objeto c# (2)
Debe marcar las clases con las que desea serializar:
[DataContract(Namespace="")]
En ese caso, el serializador de contrato de datos no usará ningún espacio de nombres para sus objetos serializados.
Bagazo
¿Cómo elimino los espacios de nombres XML de la representación XML de un objeto serializado usando DataContractSerializer?
Ese objeto necesita ser serializado a un XML de salida muy simple.
- Último y mejor: utilizando .Net 4 beta 2
- El objeto nunca necesitará ser deserializado.
- XML no debe tener ninguna xmlns: ... referencias de espacios de nombres
- Todos los subtipos de Exception y ISubObject deben ser compatibles.
- Será muy difícil cambiar el objeto original.
Objeto:
[Serializable]
class MyObj
{
string str;
Exception ex;
ISubObject subobj;
}
Necesidad de serializar en:
<xml>
<str>...</str>
<ex i:nil="true" />
<subobj i:type="Abc">
<AbcProp1>...</AbcProp1>
<AbcProp2>...</AbcProp2>
</subobj>
</xml>
Usé este código:
private static string ObjectToXmlString(object obj)
{
if (obj == null) throw new ArgumentNullException("obj");
var serializer =
new DataContractSerializer(
obj.GetType(), null, Int32.MaxValue, false, false, null,
new AllowAllContractResolver());
var sb = new StringBuilder();
using (var xw = XmlWriter.Create(sb, new XmlWriterSettings
{
OmitXmlDeclaration = true,
NamespaceHandling = NamespaceHandling.OmitDuplicates,
Indent = true
}))
{
serializer.WriteObject(xw, obj);
xw.Flush();
return sb.ToString();
}
}
De este artículo , adopté un DataContractResolver para que no haya que declarar ningún subtipo:
public class AllowAllContractResolver : DataContractResolver
{
public override bool TryResolveType(Type dataContractType, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
{
if (!knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace))
{
var dictionary = new XmlDictionary();
typeName = dictionary.Add(dataContractType.FullName);
typeNamespace = dictionary.Add(dataContractType.Assembly.FullName);
}
return true;
}
public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
{
return knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, null) ?? Type.GetType(typeName + ", " + typeNamespace);
}
}
Si tiene el corazón puesto en evitar el comportamiento predeterminado (como lo hago actualmente), crea un XmlWriter personalizado que omite escribir el espacio de nombres.
using System.IO;
using System.Xml;
public class MyXmlTextWriter : XmlTextWriter
{
public MyXmlTextWriter(Stream stream)
: base(stream, null)
{
}
public override void WriteStartElement(string prefix, string localName, string ns)
{
base.WriteStartElement(null, localName, "");
}
}
Luego, en tu escritor consumidor, algo como lo siguiente:
var xmlDoc = new XmlDocument();
DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
using (var ms = new MemoryStream())
{
using (var writer = new MyXmlTextWriter(ms))
{
serializer.WriteObject(writer, obj);
writer.Flush();
ms.Seek(0L, SeekOrigin.Begin);
xmlDoc.Load(ms);
}
}
Y la salida tendrá declaraciones de espacio de nombres, pero no habrá usos como tal:
<TestObject xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Items xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<string>Item1</string>
<string>Item2</string>
</Items>
</TestObject>