简体   繁体   中英

C# XmlSerializer define namespace with prefix in a child node

I need to create an XML document with C# that is like this:

<?xml version="1.0" encoding="utf-8"?>
<Container>
  <Info>
    <request xmlns:a="http://www.UKMail.com/Services/Contracts/DataContracts">
      <a:AuthenticationToken>token</a:AuthenticationToken>
      <a:Username>username</a:Username>
      <a:ConsignmentNumber>12345</a:ConsignmentNumber>
    </request>
  </Info>
</Container>

The critical part is the namespace definition with a prefix (xmlns:a=...) is in a child node, not the root node. I have only been able to produce this document so far:

<?xml version="1.0" encoding="utf-8"?>
<Container xmlns:a="http://www.UKMail.com/Services/Contracts/DataContracts">
  <Info>
    <a:request>
      <a:AuthenticationToken>token</a:AuthenticationToken>
      <a:Username>username</a:Username>
      <a:ConsignmentNumber>12345</a:ConsignmentNumber>
    </a:request>
  </Info>
</Container>

This is rejected by the web service - if you move the xmlns:a.. part to the request node the web service is happy with it.

This is how I am generating the XML at the moment:

class Program
    {
        static void Main(string[] args)
        {
            SerializeObject("XmlNamespaces.xml");
        }

        public static void SerializeObject(string filename)
        {
            var mySerializer = new XmlSerializer(typeof(Container));
            // Writing a file requires a TextWriter.
            TextWriter myWriter = new StreamWriter(filename);

            // Creates an XmlSerializerNamespaces and adds two
            // prefix-namespace pairs.
            var myNamespaces = new XmlSerializerNamespaces();
            myNamespaces.Add("a", "http://www.UKMail.com/Services/Contracts/DataContracts");


            Container container = new Container
            {
                Info = new CancelConsignmentRequest
                {
                    request = new CancelConsignmentRequestInfo
                    {
                        AuthenticationToken = "token",
                        ConsignmentNumber = "12345",
                        Username = "username"
                    }
                }
            };

            mySerializer.Serialize(myWriter, container, myNamespaces);
            myWriter.Close();
        }
    }

    public class Container
    {
        public CancelConsignmentRequest Info { get; set; } = new CancelConsignmentRequest();
    }

    [XmlRoot(Namespace = "http://www.UKMail.com/Services/Contracts/ServiceContracts")]
    public class CancelConsignmentRequest
    {
        [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts")]
        public CancelConsignmentRequestInfo request { get; set; } = new CancelConsignmentRequestInfo();
    }

    public class CancelConsignmentRequestInfo
    {
        [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 0)]
        public string AuthenticationToken { get; set; }
        [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 1)]
        public string Username { get; set; }

        [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 2)]
        public string ConsignmentNumber { get; set; }
    }

I have not been able to work out how to place the namespace definition with a prefix in one of the child nodes. Does anyone know how to do this in C# please? Thanks.

This is possible. The code below does what you are asking for.

class Program
{
    static void Main(string[] args)
    {
        SerializeObject("XmlNamespaces.xml");
    }

    public static void SerializeObject(string filename)
    {
        var mySerializer = new XmlSerializer(typeof(Container));
        // Writing a file requires a TextWriter.
        TextWriter myWriter = new StreamWriter(filename);

        // Creates an XmlSerializerNamespaces and adds two
        // prefix-namespace pairs.
        var myNamespaces = new XmlSerializerNamespaces();
        //myNamespaces.Add("a", "http://www.UKMail.com/Services/Contracts/DataContracts");

        Container container = new Container
        {
            Info = new CancelConsignmentRequest
            {
                request = new CancelConsignmentRequestInfo
                {
                    AuthenticationToken = "token",
                    ConsignmentNumber = "12345",
                    Username = "username"
                }
            }
        };

        mySerializer.Serialize(myWriter, container, myNamespaces);
        myWriter.Close();
    }
}

public class Container
{
    public CancelConsignmentRequest Info { get; set; } = new CancelConsignmentRequest();
}

public class CancelConsignmentRequest
{
    public CancelConsignmentRequestInfo request { get; set; } = new CancelConsignmentRequestInfo();
}

[XmlRoot(Namespace = "http://www.UKMail.com/Services/Contracts/ServiceContracts")]
public class CancelConsignmentRequestInfo
{
    [XmlNamespaceDeclarations]
    public XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces(
        new[] { new XmlQualifiedName("a", "http://www.UKMail.com/Services/Contracts/DataContracts"), });
    [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 0)]
    public string AuthenticationToken { get; set; }
    [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 1)]
    public string Username { get; set; }

    [XmlElement(Namespace = "http://www.UKMail.com/Services/Contracts/DataContracts", Order = 2)]
    public string ConsignmentNumber { get; set; }
}

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