Dan Dan - 2 months ago 17
C# Question

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?

dbc dbc
Answer

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.

Comments