简体   繁体   中英

How to prefix a XmlRoot object in c# for Serialise XML?

I need make a Header for SOAP request. After search, I success to generate my Header request in XML but i need a prefix on my XML tag.

Actually, I have generated this :

<TimeStamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="TimeStamp-2">
   <Created>2016-03-22T10:10:55.710Z</Created>
   <Expires>2016-03-22T11:10:55.710Z</Expires>
</TimeStamp>

And I need to have that :

<wsu:TimeStamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="TimeStamp-2">
   <Created>2016-03-22T10:10:55.710Z</Created>
   <Expires>2016-03-22T11:10:55.710Z</Expires>
</wsu:TimeStamp>

I was inspired by this topic ( How can I pass a username/password in the header to a SOAP WCF Service ) for create my class and generate my XML.

Here, there is my version :

class SecurityHeader : MessageHeader
{

    public override string Name
    {
        get { return "Security"; }
    }

    public override string Namespace
    {
        get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
    }

    protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
    {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
        XmlSerializer serializer1 = new XmlSerializer(typeof(TimeStamp));
        serializer1.Serialize(Console.Out, new TimeStamp(), ns);

    }
}

[XmlRoot("TimeStamp",Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public class TimeStamp
{
    public TimeStamp()
    {
        Id = "TimeStamp-2";
        Created = new Created() { Value = Created.GenerateTimeStampCreation() };
        Expires = new Expires() { Value = Expires.GenerateTimeStampExpiration() };
    }

    [XmlAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")]
    public string Id { get; set; }

    [XmlElement]
    public Created Created { get; set; }

    [XmlElement]
    public Expires Expires { get; set; }
}

You have a few issues here:

  1. Your <Created> and <Expires> elements are not in the "wsu" namespace, instead they are not in any namespace. You need to inform XmlSerializer of this by setting [XmlElement(Form = XmlSchemaForm.Unqualified)] or [XmlElement(Namespace="")] .

  2. To force the Id attribute to have an explicit namespace, you need to set [XmlAttribute(Form = XmlSchemaForm.Qualified)] .

  3. You have a typo in your namespaces. Your desired XML has the namespace xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" but sometimes you do "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" . To avoid this sort of mistake, you can make a public const string that contains the correct namespace rather than retyping the string multiple times.

Thus your fixed TimeStamp class would look like:

[XmlRoot("TimeStamp", Namespace = TimeStamp.WsuNamespace)]
public class TimeStamp
{
    public const string WsuNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";

    public TimeStamp()
    {
        Id = "TimeStamp-2";
        Created = new Created() { Value = Created.GenerateTimeStampCreation() };
        Expires = new Expires() { Value = Expires.GenerateTimeStampExpiration() };
    }

    [XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)] // Indicates this attribute is explicitly in the same namespace as the parent class
    public string Id { get; set; }

    [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] // Indicates this element is not in any namespace
    public Created Created { get; set; }

    [XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] // Indicates this element is not in any namespace
    public Expires Expires { get; set; }
}

And in your write method do:

    protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
    {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("wsu", TimeStamp.WsuNamespace);
        XmlSerializer serializer1 = new XmlSerializer(typeof(TimeStamp));
        serializer1.Serialize(writer, new TimeStamp(), ns);
    }

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