This is an offshoot from this question Why is the HttpWebRequest body val null after "crossing the Rubicon"? which was answered (one hurdle is leapt), but the next hurdle trips me up.
With this code:
public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
XDocument doc = XDocument.Parse(await Request.Content.ReadAsStringAsync());
...or this:
XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());
...and this as the incoming stringifiedXML:
<?xml version=1.0?>
<LocateAndLaunch>
<Tasks>Some Task</Tasks>
<Locations>Some Location</Locations>
</LocateAndLaunch>
...I get the exception: "System.Xml.XmlException was unhandled by user code HResult=-2146232000 Message=Root element is missing."
With this code (same stringifiedXML):
XDocument doc = XDocument.Parse(stringifiedXML);
... I get
System.InvalidOperationException was unhandled by user code HResult=-2146233079 Message=Sequence contains no elements Source=System.Core StackTrace: at System.Linq.Enumerable.First[TSource](IEnumerable`1 source) at HandheldServer.Controllers.DeliveryItemsController.d__2.MoveNext() in c:\HandheldServer\HandheldServer \Controllers\DeliveryItemsController.cs:line 109 InnerException:
IOW, depending on how I parse the incoming string, I get either "Root element is missing" or "Sequence contains no elements"
What the Deuce McAlistair MacLean Virginia Weeper?!? Isn't <LocateAndLaunch>
a root element? Aren't Some Task
and Some Location
elements?
Will I need to manually take the XML apart without being able to use XDocument
or such?
Note: From Fiddler, sending the body data (XML text) works (what I send arrives as I would hope); but even then, the XML parse code on the server fails.
Trying to send the same data from the handheld/Compact Framework client code, though, results in just the data through the "=" (something like <xml version="
being passed to the server; and then on the client, I see "This operation cannot be performed after the request has been submitted"
So based on Marcin's answer, it seems if I stick with XDocument.Parse() I should be okay, and based on TToni's answer, the data/xml itself may be bad. Here is the contents of the file:
<?xml version="1.0"?>
<LocateAndLaunch>
<Tasks>
</Tasks>
<Locations>
</Locations>
</LocateAndLaunch>
So there are quotes around the version number - but do I need to escape these somehow - is this why the data is being truncated - because when it sees the first quote (before the "1.0") it thinks that is the string termination, maybe?
Marcin, the incoming "xml" data (string) is truncated before it ever gets to the XDocument code:
[Route("api/DeliveryItems/PostArgsAndXMLFileAsStr")]
public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
string beginningInvoiceNum = string.Empty;
string endingInvoiceNum = string.Empty;
//XDocument doc = XDocument.Parse(stringifiedXML);
//XDocument doc = XDocument.Parse(await Request.Content.ReadAsStringAsync());
XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());
By using TToni's suggestion and replacing the double with single quotes:
...I'm now getting the whole string into my server method:
...but I'm still getting "Root element is missing":
System.Xml.XmlException was unhandled by user code HResult=-2146232000 Message=Root element is missing. Source=System.Xml LineNumber=0 LinePosition=0 SourceUri="" StackTrace: at System.Xml.XmlTextReaderImpl.Throw(Exception e) at System.Xml.XmlTextReaderImpl.ParseDocumentContent() at System.Xml.XmlTextReaderImpl.Read() at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options) at System.Xml.Linq.XDocument.Load(Stream stream, LoadOptions options) at System.Xml.Linq.XDocument.Load(Stream stream) at HandheldServer.Controllers.DeliveryItemsController.d__2.MoveNext() in c:\HandheldServer\HandheldServer\Controllers\DeliveryItemsController.cs:line 66 InnerException:
If I wasn't already crazy, this would drive me crazy. As it is, I don't know quite where I'm being driven. Many employers are looking for somebody who is driven; maybe this is what they mean?
Using this:
XDocument doc = XDocument.Parse(stringifiedXML);
...instead of this:
XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());
...solved the "Root element is missing" err msg; thus, I marked Marcin's answer as correct.
For those who find this page through google, but are still baffled. I believe I have found the answer thanks to a buried MS Post.
It lies in resetting the stream to the beginning utilizing:
xmlStream.Seek(0, SeekOrigin.Begin);
Without this before the read, you essentially begin your load at the end of the stream. No root element because no more stream.