Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
496 views
in Technique[技术] by (71.8m points)

.net - Serializing object with no namespaces using DataContractSerializer

How do I remove XML namespaces from an object's XML representation serialized using DataContractSerializer?

That object needs to be serialized to a very simple output XML.

  • Latest & greatest - using .Net 4 beta 2
  • The object will never need to be deserialized.
  • XML should not have any xmlns:... namespace refs
  • Any subtypes of Exception and ISubObject need to be supported.
  • It will be very difficult to change the original object.

Object:

 [Serializable] 
 class MyObj
 {
     string str;
     Exception ex;
     ISubObject subobj;
 } 

Need to serialize into:

<xml>
  <str>...</str>
  <ex i:nil="true" />
  <subobj i:type="Abc">
     <AbcProp1>...</AbcProp1>
     <AbcProp2>...</AbcProp2>
  </subobj>
</xml>

I used this code:

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();
    }
}

From this article I adopted a DataContractResolver so that no subtypes have to be declared:

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);
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to mark the classes you want to serialize with:

[DataContract(Namespace="")]

In that case, the data contract serializer will not use any namespace for your serialized objects.

Marc


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...