How can I parse this XML (without getting "Root element is missing" or "Sequence contains no elements")?

StackOverflow https://stackoverflow.com/questions/22413587

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"

UPDATE

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?

UPDATE 2

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());

UPDATE 3

By using TToni's suggestion and replacing the double with single quotes:

...I'm now getting the whole string into my server method:

enter image description here

...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?

UPDATE 4

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.

有帮助吗?

解决方案 2

Sample XML you've provided works just fine with XDocument:

var stringifiedXML = @"<?xml version=""1.0""?>
    <LocateAndLaunch>
        <Tasks>Some Task</Tasks>
        <Locations>Some Location</Locations>
    </LocateAndLaunch>";

XDocument doc = XDocument.Parse(stringifiedXML);

var tasks = (string)doc.Root.Element("Tasks");
var locations = (string)doc.Root.Element("Locations");

So your problem is with await Request.Content.ReadAsStringAsync(), not with XDocument.

Make sure ReadAsStringAsync() returns what you need first.

其他提示

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.

If that is really your stringified XML, your XML declaration is broken. You need to enclose the version number in single or double quotes, so instead of <?xml version=1.0?> do <?xml version="1.0"?> or <?xml version='1.0'?>. That would also explain the errors IMO.

Syntax for XML declaration: http://www.w3.org/TR/REC-xml/#NT-XMLDecl

this can be achieved easily by setting a custom parameter binding as mentioned in the below blog post . i tried in one of my projects where i had to use raw xml post for a WebApi

Check this blog entry

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top