Question

I have two DataContracts which I am serializing to XML using a DataContractSerializer.

I specify different namespace for the two different DataContracts however, there is a DataMember in each DataContract which is of the same POD type. This POD is in a different c# namespace.

I would like to know if there is a way of specifying the namespace to use for this DataMember depending on which containing type it belongs to.

For example:

namespace NamespaceShared
{
    using System.Runtime.Serialization;

    [DataContract]
    public sealed class SharedType
    {
        [DataMember(IsRequired = true)]
        public int ValueOne { get; set; }

        [DataMember(IsRequired = true)]
        public int ValueTwo { get; set; }
    }
}

namespace NamespaceOne
{
    using System.Runtime.Serialization;
    using NamespaceShared;

    [DataContract(Namespace = "http://namespace.one")]
    public sealed class DataContractOne
    {
        [DataMember(IsRequired = true)]
        //[SomeNamespaceAttribute("http://namespace.one")]
        private SharedType SharedValue { get; set; }
    }
}

namespace NamespaceTwo
{
    using System.Runtime.Serialization;
    using NamespaceShared;

    [DataContract(Namespace = "http://namespace.two")]
    public sealed class DataContractTwo
    {
        [DataMember(IsRequired = true)]
        //[SomeNamespaceAttribute("http://namespace.two")]
        private SharedType SharedValue { get; set; }
    }
}

I'm looking for something which would provide the functionality of SomeNamespaceAttribute in the code above.

Note: I'm not looking for suggestions on how better to organise my DataContracts because unfortunately I'm refactoring legacy code and the XML format can't be changed.

Était-ce utile?

La solution

DataContractSerializer does not expose as fine grained control over the XML generation, so this sort of attribute is not inherently available. However, you could subclass the shared class (assuming you can get rid of the sealed access modifier), with two different DataContract attributes with different namespaces.

namespace NamespaceShared
{
    using System.Runtime.Serialization;

    public class SharedType
    {
        [DataMember(IsRequired = true)]
        public int ValueOne { get; set; }

        [DataMember(IsRequired = true)]
        public int ValueTwo { get; set; }
    }

    [DataContract(Namespace = "http://namespace.one")]
    public class SharedTypeOne : SharedType
    {
    }

    [DataContract(Namespace = "http://namespace.two")]
    public class SharedTypeTwo : SharedType
    {
    }
}

namespace NamespaceOne
{
    using System.Runtime.Serialization;
    using NamespaceShared;

    [DataContract(Namespace = "http://namespace.one")]
    public sealed class DataContractOne
    {
        [DataMember(IsRequired = true)]
        private SharedTypeOne SharedValue { get; set; }
    }
}

namespace NamespaceTwo
{
    using System.Runtime.Serialization;
    using NamespaceShared;

    [DataContract(Namespace = "http://namespace.two")]
    public sealed class DataContractTwo
    {
        [DataMember(IsRequired = true)]
        private SharedTypeTwo SharedValue { get; set; }
    }
}

If all else fails, you could edit the raw XML coming out of the service using a technique similar to that which is used to change the auto-generated prefixes. This MSDN blog post details the overall process.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top