Using the [ContractNamespace] attribute to customize the namespace for POCO types
In .NET 3.5 SP1, DataContractSerializer was enhanced to support POCO types that weren’t marked with any serialization attributes at all. You can find my previous post about serializing POCO types here. But in some cases, you may want to customize the XML namespace of your POCO types without necessarily having to fall back to the [DataContract]/[DataMember] model. The way to do this is by using an assembly-level attribute called [ContractNamespace]. This attribute allows you to either set an XML namespace for DataContractSerializer for all the types in your assembly, or to set an XML namespace for specific CLR namespaces within your assembly.
So for example, the following POCO type:
namespace MyNs
{
public class POCO
{
public string Data { get; set; }
}
}
Would traditionally get serialized with a default XML namespace:
<POCO xmlns="https://schemas.datacontract.org/2004/07/MyNs" xmlns:i="https://www.w3.org/2001/XMLSchema-instance">
<Data i:nil="true" />
</POCO>
But if you happen to have the assembly level attribute:
[assembly:ContractNamespace("https://myXmlNamespace")]
Or:
[assembly:ContractNamespace("https://myXmlNamespace", ClrNamespace="MyNs")]
, then "https://myXmlNamespace" will be used for the POCO type’s serialization:
<POCO xmlns="https://myXmlNamespace" xmlns:i="https://www.w3.org/2001/XMLSchema-instance">
<Data i:nil="true" />
</POCO>
So the ContractNamespaceAttribute allows you to either choose a default XML namespace for the entire assembly, or map the types in a specific CLR namespace to the XML namespace of your choosing.
Note that ContractNamespaceAttribute applies not only to POCO types, but to all other serializable types as well. So,
namespace MyNs
{
[DataContract
public class POCO
{
[DataMember]
public string Data { get; set; }
}
}
Would also be serialized as:
<POCO xmlns="https://myXmlNamespace" xmlns:i="https://www.w3.org/2001/XMLSchema-instance">
<Data i:nil="true" />
</POCO>
If the [ContractNamespace] attribute were present. However, DataContracts can override the ContractNamespace default by setting their own namespace on the type itself. So,
namespace MyNs
{
[DataContract(Namespace="https://POCONamespace")]
public class POCO
{
[DataMember]
public string Data { get; set; }
}
}
Would get serialized as:
<POCO xmlns="https://POCONamespace" xmlns:i="https://www.w3.org/2001/XMLSchema-instance">
<Data i:nil="true" />
</POCO>
Regardless of any [ContractNamespace] attributes.