代码之家  ›  专栏  ›  技术社区  ›  Yngve B-Nilsen

在SOAP请求中,XML元素被包装在额外的标记中

  •  0
  • Yngve B-Nilsen  · 技术社区  · 14 年前

    嗨,我有一个服务代理,有一个方法:

    void SendRequest(MyMessage msg);
    

    mymessage定义如下:

    [MessageContract(IsWrapped=false)]
    public class MyMessage{
        [MessageBodyMember(Order=0)]
        public XmlElement Body;
    
        public MyMessage(XmlElement Body){
            this.Body = Body;
        }
    }
    

    现在,问题是当我发送请求时,主体被这样一个标签包裹:

    <s:Body>
        <Body>
             <MyMessage>
                   <SomeData>Hello world</SomeData>
             </MyMessage>
        </Body>
    </s:Body>
    

    当我真正想要的是:

    <s:Body>
        <MyMessage>
                   <SomeData>Hello world</SomeData>
        </MyMessage>
    </s:Body>
    

    有人能帮忙吗?我开始绝望了!:

    编辑:我想发送xmlement的原因是服务将接受各种XML格式,并在服务器端进行XSD验证和转换。这只是一种包装。

    我也不可能让端点服务器简单地接受“错误的”XML结构,因为我无法控制它。

    1 回复  |  直到 14 年前
        1
  •  2
  •   Yngve B-Nilsen    14 年前

    好吧,看来我得完全放弃WCF才行。

    我所做的是创建两个简单的方法:

        XDocument ConstructSoapEnvelope(string messageId, string action, XDocument body)
        {
            XDocument xd = new XDocument();
            XNamespace s = "http://schemas.xmlsoap.org/soap/envelope/";
            XNamespace a = "http://www.w3.org/2005/08/addressing";
    
            XElement soapEnvelope = new XElement(s + "Envelope", new XAttribute(XNamespace.Xmlns + "s", s), new XAttribute(XNamespace.Xmlns + "a", a));
            XElement header = new XElement(s + "Header");
            XElement xmsgId = new XElement(a + "MessageID", "uuid:" + messageId);
            XElement xaction = new XElement(a + "Action", action);
            header.Add(xmsgId);
            header.Add(xaction);
    
            XElement soapBody = new XElement(s + "Body", body.Root);
            soapEnvelope.Add(header);
            soapEnvelope.Add(soapBody);
            xd = new XDocument(soapEnvelope);
            return xd;
        }
    
        string HttpSOAPRequest(XmlDocument doc, string add, string proxy, X509Certificate2Collection certs)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(add);
            req.ClientCertificates = certs;
            if (proxy != null) req.Proxy = new WebProxy("", true);
    
            req.Headers.Add("SOAPAction", "\"\"");
    
            req.ContentType = "text/xml;charset=\"utf-8\"";
            req.Accept = "text/xml";
            req.Method = "POST";
            Stream stm = req.GetRequestStream();
            doc.Save(stm);
            stm.Close();
            WebResponse resp = req.GetResponse();
            stm = resp.GetResponseStream();
            StreamReader r = new StreamReader(stm);
    
           return r.ReadToEnd();
        }
    

    constructsoapenvelope只需创建一个带有头部和主体的SOAP信封(通过WS-Addressing根据我的需要定制)

    httpsoaprequest是这里找到的稍微修改过的版本: http://www.eggheadcafe.com/articles/20011103.asp

    为了让我的SSL通信工作,我不得不修改它来接受客户端证书。

    希望这也能帮助别人!:)