Олег Кислов
Олег Кислов

Reputation: 21

Accepting SOAP data as raw XML

I am trying to write a .NET IIS web service using the System.ServiceModel namespace. My service shall read the startTag node from the incoming packet as RAW XML rather than a deserialised .NET class, but I can't seem to do it. Here is a sample SOAP packet:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:tmk="http://schemas.datacontract.org/2004/07/TMK.Catalog">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:Catalog>
         <tem:document>
            <tmk:CHRMAS03>
                 <startTag>
                <myTag>
                    <answer>Hello world!</answer>
                </myTag>
            </startTag>
            </tmk:CHRMAS03>
         </tem:document>
      </tem:Catalog>
   </soapenv:Body>
</soapenv:Envelope>

And here is my web service:

using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Xml.XPath;

[ServiceContract]
public interface IContract
{
    [OperationContract]
    string Catalog(Point document);
}

[DataContract]
public class Point
{
    [DataMember]
    public XPathDocument CHRMAS03;

    public Point (XPathDocument document)
    {
        this.CHRMAS03= document;
    }
}
public class Service1 : IContract
{
    public string Catalog (Point document)
    {
        if(document.CHRMAS03!=null) 
        {
        try
        {
            XPathNavigator navigator = document.CHRMAS03.CreateNavigator();
            XPathNodeIterator iterator1 =  navigator.Select("startTag/myTag/answer");
            if(iterator1==null) {return "crash"; }
            int a = iterator1.Count; // Exception!
            return "success"; 
        }
            catch(Exception e)
            {
                return e.Message + e.StackTrace;
            }
        }
        return "fail";
    }

When I send the packet specified above to my web service, this line:

int a = iterator1.Count

throw an exception:

   Object reference not set to an instance of an object.
   at MS.Internal.Xml.Cache.XPathDocumentNavigator.get_NameTable()
   at MS.Internal.Xml.Cache.XPathDocumentElementChildIterator..ctor(XPathDocumentNavigator parent, String name, String namespaceURI)
   at MS.Internal.Xml.Cache.XPathDocumentNavigator.SelectChildren(String name, String namespaceURI)
   at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
   at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
   at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
   at MS.Internal.Xml.XPath.Query.MoveNext()
   at MS.Internal.Xml.XPath.Query.get_Count()
   at TMK.Catalog.Service1.Catalog(Point document)

How shall I redefne the CHRMAS03 field in order for it to take the raw XML content of the startTag node, as a string that I can parse manually or a working instance any standard .NET class for reading XML, such as XmlReader or XmlNode?

Upvotes: 2

Views: 88

Answers (2)

Олег Кислов
Олег Кислов

Reputation: 21

My XPath query:

startTag/myTag/answer

did not work because the XML is parsed with whitespace elements between the tags. I switched to XMLDocument and modified my code to skip them:

XmlNode root = doc.DocumentElement;
foreach (XmlNode idoc in root.ChildNodes)
{
    if (idoc.Name == "#whitespace") continue;
    /* ... processing ... */
}

I think this whitespace elements caused XPathNodeIterator.Count to throw.

Upvotes: 0

Ching Chang
Ching Chang

Reputation: 85

"startTeg/myTeg/answer" should be "startTag/myTag/answer"?

Upvotes: 1

Related Questions