在序列化期间将名称空间和前缀添加到soap消息头

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在序列化期间将名称空间和前缀添加到soap消息头相关的知识,希望对你有一定的参考价值。

我试图生成具有以下结构的xml文件:

  <?xml version="1.0" encoding="UTF-8"?>
  <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
   <soap-env:Header>
     <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wsse curity-secext-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:mustunderstand="1">
      <wsse:UsernameToken>
        <wsse:Username>username</wsse:Username>
        <wsse:Password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-t oken-profile-1.0#passwordtext">secret</wsse:Password>
     </wsse:UsernameToken>
   </wsse:Security>
 </soap-env:Header>

我得到的xml是:

<?xml version="1.0" encoding="utf-8"?>
<soap-env:Envelope xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
 <soap-env:Header>
   <wsse:Security>
     <wsse:UsernameToken>
       <wsse:Username>someuser</wsse:Username>
       <wsse:Password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#passwordtext">somepass</wsse:Password>
     </wsse:UsernameToken>
   </wsse:Security>
 </soap-env:Header>

我的课程是:

[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")] //
public class SoapEnvelope<T>
{
    public Header Header { get; set; }

    [XmlElement("Body")]
    public GenericBody<T> GenericBody { get; set; }
}


[XmlRoot(ElementName = "Security", Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public class Header
{
    public Security Security { get; set; }
}


 public class Security
{
    public UsernameToken UsernameToken { get; set; }
}

 public class UsernameToken
{
    public string Username { get; set; }

    public Passwords Password { get; set; }
}

public class Passwords
{
    [XmlAttribute("type")]
    public string Type { get; set; } 
    [XmlText]
    public string Passowrd { get; set; }
}

问题是,当我使用类XmlSerializerNamespaces声明名称空间时,如下所示:

 var serializer = new XmlSerializer(typeof(SoapEnvelope<T>));

        var memoryStream = new MemoryStream();
        var xmlSettings = new XmlWriterSettings { Indent = false, Encoding = Encoding.UTF8 };
        var soapwriter = XmlWriter.Create(memoryStream, xmlSettings);

        var ns = new XmlSerializerNamespaces();
        ns.Add("soap-env", "http://schemas.xmlsoap.org/soap/envelope/");
        ns.Add("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
        //ns.Add("soap", "http://schemas.xmlsoap.org/soap/envelope/");
        serializer.Serialize(soapwriter, soapEnveloped, ns);
        soapwriter.Close();

我在根元素中获得了两个名称空间,而在元素Security中没有名称空间。还有我如何设法在Security元素中添加另外两个名称空间:xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:mustunderstand="1"我在搜索这些天时尝试了不同的方法,但它们似乎都不起作用。

谢谢。

答案

我在根元素中获得了两个名称空间

这在语义上等同于您尝试生成的XML。您无法使用XmlSerializer来控制它 - 它将要做的第一件事是在根元素中编写所有命名空间绑定。但是,你不应该有任何理由对此表示不满。

还有我如何设置在Security元素中添加另外两个名称空间:xmlns:soap =“http://schemas.xmlsoap.org/soap/envelope/”soap:mustunderstand =“1”

这里有两件事:一件是命名空间绑定,一件是属性。如果正确添加属性,则命名空间绑定将与其他绑定一起添加到根目录中:

public class Security
{
    [XmlAttribute("mustunderstand", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public int MustUnderstand { get; set; }

    public UsernameToken UsernameToken { get; set; }
}

这给出了下面的输出,它等于你的预期输出:

<soap-env:Envelope xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-2004
01-wss-wssecurity-secext-1.0.xsd" xmlns:soap-env="http://schemas.xmlsoap.org/soa
p/envelope/">
  <soap-env:Header>
    <wsse:Security soap-env:mustunderstand="1">
      <wsse:UsernameToken>
        <wsse:Username>someuser</wsse:Username>
        <wsse:Password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401
-wss-username-token-profile-1.0#passwordtext">somepass</wsse:Password>
      </wsse:UsernameToken>
    </wsse:Security>
  </soap-env:Header>
</soap-env:Envelope>

有关工作演示,请参阅this fiddle

以上是关于在序列化期间将名称空间和前缀添加到soap消息头的主要内容,如果未能解决你的问题,请参考以下文章

Axis2 Web 服务名称空间前缀转换

如何在 .NET 中的反序列化期间指定 XML 序列化属性以支持命名空间前缀?

如何在没有名称空间的情况下将XML字符串附加到DOMDocument

WCF中记录SOAP消息日志

更改 XML 标记前缀 SOAP

将命名空间添加到元素并在没有别名的情况下进行序列化