Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

.NET C# Soap Server Deserialization Issues

1,351 views
Skip to first unread message

Matt Wood

unread,
Aug 22, 2005, 3:16:23 AM8/22/05
to
Hi,

I am a .NET Web Services newbie, so please forgive my ignorance/poor
terminology when describing my issue. Please let me know if I have not
provided enough information, or posted to the wrong newsgroup.

I have written a Web Service for a customer which expects a SOAP message
with Document/Literal encoding, and uses
RoutingStyle=SoapServiceRoutingStyle.RequestElement to route the SOAP body
message to my Web Method. The Web Method expects a string as its parameter
and then feeds that string to an XML deserializer which maps the XML
elements contained within the string to my custom objects, then performs an
insert/update on an SQL Server database depending on whether the elements
exist in the database or not.

The example SOAP request generated by my Webservice is:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SendDealerData xmlns="urn:SendDealerData">
<dstDealerData>string</dstDealerData>
</SendDealerData>
</soap:Body>
</soap:Envelope>

Where the dstDealerData node contains the string which is passed to my Web
Method.

My issue is that when I send a request from a c# web services client, all
works perfectly, however when my customer sends a request from their client
(which is generated out of an Oracle database, not sure about the platform)
the request fails, returning the following SOAP fault:

<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>System.Web.Services.Protocols.SoapException: Server was
unable to read request. ---&gt; System.InvalidOperationException: There is
an error in XML document (1, 591). ---&gt; System.Xml.XmlException:
'Element' is an invalid node type. Line 1, position 591.
at System.Xml.XmlReader.ReadElementString()
at
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read2_SendDealerData()
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
xmlReader, String encodingStyle)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
xmlReader)
at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
--- End of inner exception stack trace ---
at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
at System.Web.Services.Protocols.WebServiceHandler.Invoke()
at
System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faultstring>
<detail />
</soap:Fault>

I have used a trace program to analyse the differences in SOAP requests (the
customer and myself have both sent the same data within the
<dstDealerData></dstDealerData> nodes of the SOAP envelope) - the
difference I have found is that when the data is sent via my c# client, all
'<' and '>' characters within the dstDealerData node are substituted for
'&lt;' and '&gt;' respectively, whilst when my customer sends the request
from their environment, the '<' and '>' characters are retained within the
dstDealerData node. If I use the data from my customer's soap request and
send that from my c# client, all works fine as the c# client performs the
necessary character substitution.

I have tried writing a SOAP Extension which intercepts the incoming SOAP
message before it is passed to my Web Method (in the BeforeDeserialize SOAP
message stage) and performs the necessary character substitution on the '<'
and '>' characters within the <dstDealerData></dstDealerData> nodes of the
message, then rewrites the message to the
HttpContext.Current.Items["SoapMessage"] object, however I now receive the
following SOAP fault:

<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>System.Web.Services.Protocols.SoapException: The root
element for the request could not be determined. When RoutingStyle is set to
RequestElement, SoapExtensions configured via an attribute on the method
cannot modify the request stream before it is read. The extension must be
configured via the SoapExtensionTypes element in web.config, or the request
must arrive at the server as clear text. ---&gt; System.Xml.XmlException:
The root element is missing.
at System.Xml.XmlTextReader.Read()
at System.Xml.XmlReader.MoveToContent()
at
System.Web.Services.Protocols.SoapServerProtocolHelper.GetRequestElement()
at
System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
--- End of inner exception stack trace ---
at
System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type,
HttpContext context, HttpRequest request, HttpResponse response,
Boolean&amp; abortProcessing)</faultstring>
<detail />
</soap:Fault>

Which is obviously indicating that I can not use a SOAP extension when the
routing style is set to Request Element. I have asked the customer whether
it is possible for them to do the character substitution on their end,
however they have stated that they cannot do this.

What other options do I have for making my Web Method accept the data in the
format they are sending it? Unfortunately I have to make the web service
conform to the customer's requirements so any modifications must be made on
my end.

Many thanks,

Matt Wood

Marvin Smit

unread,
Aug 29, 2005, 11:45:04 AM8/29/05
to
Hi,

your dealing with the XML encoding. When you see the XML specs, there
are only so many characters that are allowed inside nodes.

Some of these are "not representable as characters" in XML (like all
the low ascii chars like "BELL" , "PRINT", "CLEARSCREEN", etc.

And then you have the characters that need to be 'XML escaped' to be
considered 'plain text' instead of a signature character for XML.
These 5 are:

< (Less than) changes into &lt;
> (Greater than) changes into &gt;
& (Ampersant) changes into &amp;
' (Apos) changes into &apos;
" (Quote) changes into &quot;

Since you defined the dstDealerData to be of type "string", it MUST BE
XML escaped!

So, what you are seeying in your two message is, one that is correctly
XML escaped and one that is not. The one that is not will never run
through the WebService.

To change this (option 1 - Server Side):
Make the dstDealerData an xsd:any

To change this (option 2 - Client Side):
Make sure to XML escape (XMLDocument.LoadXml( xxx ); string =
XMLDocument.text) the data.

Hope this helps,

Marvin Smit.

On Mon, 22 Aug 2005 17:16:23 +1000, "Matt Wood" <ma...@caval.edu.au>
wrote:

Wood@discussions.microsoft.com Matt Wood

unread,
Aug 30, 2005, 4:22:02 AM8/30/05
to
Thanks Marvin,

You were spot on - had to change the type of dstDealerData from string to
XmlDocument and all worked fine.

Cheers,

Matt

"Marvin Smit" wrote:

> Hi,
>
> your dealing with the XML encoding. When you see the XML specs, there
> are only so many characters that are allowed inside nodes.
>
> Some of these are "not representable as characters" in XML (like all
> the low ascii chars like "BELL" , "PRINT", "CLEARSCREEN", etc.
>
> And then you have the characters that need to be 'XML escaped' to be
> considered 'plain text' instead of a signature character for XML.
> These 5 are:
>
> < (Less than) changes into <

> > (Greater than) changes into >
> & (Ampersant) changes into &


> ' (Apos) changes into &apos;
> " (Quote) changes into "
>

> >unable to read request. ---> System.InvalidOperationException: There is
> >an error in XML document (1, 591). ---> System.Xml.XmlException:

> >'Element' is an invalid node type. Line 1, position 591.
> > at System.Xml.XmlReader.ReadElementString()
> > at
> >Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read2_SendDealerData()
> > --- End of inner exception stack trace ---
> > at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
> >xmlReader, String encodingStyle)
> > at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
> >xmlReader)
> > at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
> > --- End of inner exception stack trace ---
> > at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
> > at System.Web.Services.Protocols.WebServiceHandler.Invoke()
> > at
> >System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()</faultstring>
> > <detail />
> > </soap:Fault>
> >
> >I have used a trace program to analyse the differences in SOAP requests (the
> >customer and myself have both sent the same data within the
> ><dstDealerData></dstDealerData> nodes of the SOAP envelope) - the
> >difference I have found is that when the data is sent via my c# client, all
> >'<' and '>' characters within the dstDealerData node are substituted for

> >'<' and '>' respectively, whilst when my customer sends the request

> >from their environment, the '<' and '>' characters are retained within the
> >dstDealerData node. If I use the data from my customer's soap request and
> >send that from my c# client, all works fine as the c# client performs the
> >necessary character substitution.
> >
> >I have tried writing a SOAP Extension which intercepts the incoming SOAP
> >message before it is passed to my Web Method (in the BeforeDeserialize SOAP
> >message stage) and performs the necessary character substitution on the '<'
> >and '>' characters within the <dstDealerData></dstDealerData> nodes of the
> >message, then rewrites the message to the
> >HttpContext.Current.Items["SoapMessage"] object, however I now receive the
> >following SOAP fault:
> >
> > <soap:Fault>
> > <faultcode>soap:Server</faultcode>
> > <faultstring>System.Web.Services.Protocols.SoapException: The root
> >element for the request could not be determined. When RoutingStyle is set to
> >RequestElement, SoapExtensions configured via an attribute on the method
> >cannot modify the request stream before it is read. The extension must be
> >configured via the SoapExtensionTypes element in web.config, or the request

> >must arrive at the server as clear text. ---> System.Xml.XmlException:

> >The root element is missing.
> > at System.Xml.XmlTextReader.Read()
> > at System.Xml.XmlReader.MoveToContent()
> > at
> >System.Web.Services.Protocols.SoapServerProtocolHelper.GetRequestElement()
> > at
> >System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
> > --- End of inner exception stack trace ---
> > at
> >System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
> > at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
> > at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type,
> >HttpContext context, HttpRequest request, HttpResponse response,

> >Boolean& abortProcessing)</faultstring>

Marvin Smit

unread,
Aug 30, 2005, 6:51:35 AM8/30/05
to
Hi,

:)

Ehh, please be aware that there is NO validation happening by
default...

Hope this helps,

Marvin Smit.

verhaalen

unread,
Aug 9, 2011, 12:17:34 PM8/9/11
to
> unable to read request. &gt; System.InvalidOperationException: There is
> an error in XML document (1, 591). &gt; System.Xml.XmlException:

> 'Element' is an invalid node type. Line 1, position 591.
> at System.Xml.XmlReader.ReadElementString()
> at
>
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read2_SendDealerData()
> End of inner exception stack trace
> at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
> xmlReader, String encodingStyle)
> at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader
> xmlReader)
> at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
> End of inner exception stack trace
> must arrive at the server as clear text. &gt; System.Xml.XmlException:

> The root element is missing.
> at System.Xml.XmlTextReader.Read()
> at System.Xml.XmlReader.MoveToContent()
> at
> System.Web.Services.Protocols.SoapServerProtocolHelper.GetRequestElement()
> at
> System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
> End of inner exception stack trace
> at
> System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
> at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
> at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type,
> HttpContext context, HttpRequest request, HttpResponse response,
> Boolean&amp; abortProcessing)</faultstring>
> <detail />
> </soap:Fault>
>
> Which is obviously indicating that I can not use a SOAP extension when the
> routing style is set to Request Element. I have asked the customer whether
> it is possible for them to do the character substitution on their end,
> however they have stated that they cannot do this.
>
> What other options do I have for making my Web Method accept the data in the
> format they are sending it? Unfortunately I have to make the web service
> conform to the customer's requirements so any modifications must be made on
> my end.
>
> Many thanks,
>
> Matt Wood
>
I know it&rsquo;s been a very long time since the original post.

Refering to &ldquo;System.Web.Services.Protocols.SoapException: The root

element for the request could not be determined. When RoutingStyle is set to
RequestElement, SoapExtensions configured via an attribute on the method
cannot modify the request stream before it is read. The extension must be
configured via the SoapExtensionTypes element in web.config, or the request
must arrive at the server as clear text&rdquo;

I received the exact message from a Windows forms application that was sending
a
large dataset to a Web Service.

Solution: In the Web.config of the Web Service, within <system.web> add
<httpRuntime maxRequestLength="8192"/>
The default maxRequestLength is 4096.
0 new messages