简体   繁体   中英

Removing namespaces serializing with DataContractSerializer

I use the DataContractSerializer in order to serialize an object. Here is my code:

private string XmlSerial<T>(T instance)
{
    DataContractSerializer Serializer = new DataContractSerializer(typeof(T));
    using (MemoryStream memoryStream = new MemoryStream())
    {
        Serializer.WriteObject(memoryStream, instance);
        return Encoding.Default.GetString(memoryStream.ToArray());
    }
}

Here is my output:

<WS_IN_GetAccountCredit xmlns="http://schemas.datacontract.org/2004/07/WcfWebService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <GetAccountCreditParams xmlns:a="http://schemas.datacontract.org/2004/07/RestConsumer">
    <a:Password>String content</a:Password>
    <a:UserName>String content</a:UserName>
  </GetAccountCreditParams>
  <WSIdentity xmlns:a="http://schemas.datacontract.org/2004/07/RestConsumer">
    <a:WS_PassWord>String content</a:WS_PassWord>
    <a:WS_UserName>String content</a:WS_UserName>
  </WSIdentity>
</WS_IN_GetAccountCredit>

I now need to remove xmlns:i and xmlns:a and also set the Indent = true; , how can I do it?

Firstly, you need to mark all your classes with [DataContract(Namespace = "http://schemas.datacontract.org/2004/07/WcfWebService")] to declare that each class should be serialized in that namespace. Having done that, you must also mark each or property to be serialized with [DataMember] since DataContractSerializer is opt-in.

Thus:

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/WcfWebService")]
public class WS_IN_GetAccountCredit
{
    [DataMember]
    public GetAccountCreditParams GetAccountCreditParams { get; set; }
    [DataMember]
    public WSIdentity WSIdentity { get; set; }
}

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/WcfWebService")]
public class GetAccountCreditParams
{
    [DataMember]
    public string Password { get; set; }
    [DataMember]
    public string UserName { get; set; }
}

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/WcfWebService")]
public class WSIdentity
{
    [DataMember]
    public string WS_PassWord { get; set; }
    [DataMember]
    public string WS_UserName { get; set; }
}

Secondly, as for indentation, you can create an XmlWriterSettings with the desired indentation, then create an XmlWriter from it and use it for serialization, as in the following extension methods:

public static class DataContractSerializerHelper
{
    public static string GetXml<T>(T obj, DataContractSerializer serializer)
    {
        using (var textWriter = new StringWriter())
        {
            var settings = new XmlWriterSettings { Indent = true, IndentChars = "    " };
            using (var xmlWriter = XmlWriter.Create(textWriter, settings))
            {
                serializer.WriteObject(xmlWriter, obj);
            }
            return textWriter.ToString();
        }
    }

    public static string GetXml<T>(T obj)
    {
        var serializer = new DataContractSerializer(typeof(T));
        return GetXml(obj, serializer);
    }
}

Thirdly, as for removing the standard namespace xmlns:i="http://www.w3.org/2001/XMLSchema-instance" I don't believe that is possibly directly with DataContractSerializer . ( XmlSerializer allows more control.) It's harmless, but you could manually remove it following the instructions in Avoiding using the “http://www.w3.org/2001/XMLSchema-instance” namespace with .Net DataContractSerializer .

[DataContract(Namespace = "")]

on top of each class makes it a lot nicer. It removes the datacontract namespaces and the ugly node prefixes. However, the standard namespace stays. That was ok for my case.

Before:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://schemas.datacontract.org/2004/07/MyClassname">
  <prop1>true</prop1>
  <prop2 xmlns:d2p1="http://schemas.datacontract.org/2004/07/MySubclassname">
    <d2p1:sub>true</d2p1:sub>
  </prop2>
</root>

After:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <prop1>true</prop1>
  <prop2>
    <sub>true</sub>
  </prop2>
</root>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM