我如何解析这个XML(没有得到" Root元素丢失"或" Sequence不包含任何元素")?

时间:2014-03-14 19:01:15

标签: c# linq-to-xml frombodyattribute

这是这个问题Why is the HttpWebRequest body val null after "crossing the Rubicon"?的一个分支,这个问题得到了回答(一个障碍是跳过),但是下一个障碍让我感到高兴。

使用此代码:

public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
    XDocument doc = XDocument.Parse(await Request.Content.ReadAsStringAsync()); 

......或者这个:

XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());

...这是传入的stringifiedXML:

<?xml version=1.0?>
<LocateAndLaunch>
    <Tasks>Some Task</Tasks>
    <Locations>Some Location</Locations>
</LocateAndLaunch>

...我得到异常:&#34; System.Xml.XmlException未被用户代码处理HResult = -2146232000消息=缺少根元素。&#34;

使用此代码(相同的stringifiedXML):

XDocument doc = XDocument.Parse(stringifiedXML);

......我得到了

  

System.InvalidOperationException未被用户代码处理   HResult = -2146233079 Message = Sequence不包含任何元素   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:第109行InnerException:

IOW,根据我解析传入字符串的方式,我得到&#34; 根元素丢失 &#34;或&#34; 序列不包含任何元素 &#34;

Deuce McAlistair MacLean Virginia Weeper是什么?!?不是<LocateAndLaunch>根元素吗? Aren&#t; t Some TaskSome Location元素?

我是否需要手动将XML拆分而无法使用XDocument或类似的?

注意:来自Fiddler,发送正文数据(XML文本)可以正常工作(我发送的内容正如我所希望的那样到达);但即使这样,服务器上的XML解析代码也会失败。

尝试从掌上电脑/ Compact Framework客户端代码发送相同的数据,只会通过&#34; =&#34; (例如<xml version="被传递到服务器;然后在客户端上,我看到&#34; 在提交请求后无法执行此操作&#34;

更新

基于Marcin的答案,似乎我坚持使用XDocument.Parse()我应该没问题,并且根据TToni的回答,data / xml本身可能不好。以下是文件的内容:

<?xml version="1.0"?>
<LocateAndLaunch>
    <Tasks>
    </Tasks>
    <Locations>
    </Locations>
</LocateAndLaunch>

所以版本号附近有引号 - 但我是否需要以某种方式逃避这些 - 这就是数据被截断的原因 - 因为当它看到第一个引用时(在&#34; 1.0&#34;之前)它认为这是字符串终止,也许?

更新2

Marcin,来自&#34; xml&#34; data(字符串)在到达XDocument代码之前被截断:

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

更新3

使用TToni的建议并用单引号替换双:

...我现在将整个字符串放入我的服务器方法中:

enter image description here

...但我仍然得到&#34; 缺少根元素 &#34;:

System.Xml.XmlException未被用户代码处理   的HResult = -2146232000   消息=缺少根元素。   来源=的System.Xml   LineNumber上= 0   LinePosition = 0   SourceUri =&#34;&#34;   堆栈跟踪:        在System.Xml.XmlTextReaderImpl.Throw(例外e)        在System.Xml.XmlTextReaderImpl.ParseDocumentContent()        在System.Xml.XmlTextReaderImpl.Read()        在System.Xml.Linq.XDocument.Load(XmlReader reader,LoadOptions选项)        在System.Xml.Linq.XDocument.Load(Stream stream,LoadOptions选项)        在System.Xml.Linq.XDocument.Load(流媒体流)        at HandheldServer.Controllers.DeliveryItemsController.d__2.MoveNext()in c:\ HandheldServer \ HandheldServer \ Controllers \ DeliveryItemsController.cs:第66行   InnerException:

如果我已经疯了,这会让我发疯。事实上,我并不知道自己被驱赶的地方。许多雇主正在寻找一个被驱使的人;也许这就是他们的意思?

更新4

使用此:

XDocument doc = XDocument.Parse(stringifiedXML);

......而不是:

XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());

...解决了&#34; Root元素缺失&#34;错误的消息;因此,我将Marcin的答案标记为正确。

4 个答案:

答案 0 :(得分:9)

对于那些通过谷歌找到此页面的人,但仍然感到困惑。我相信我已经找到了答案,感谢被埋没的MS Post

使用以下方法将流重置为开头:

xmlStream.Seek(0, SeekOrigin.Begin);

在读取之前没有这个,你基本上开始在流的末尾加载。没有根元素,因为没有更多的流。

答案 1 :(得分:6)

您提供的示例XML与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");

所以问题出在await Request.Content.ReadAsStringAsync(),而不是XDocument

确保ReadAsStringAsync()首先返回您需要的内容。

答案 2 :(得分:2)

如果这确实是您的字符串化XML,那么您的XML声明就会被破坏。您需要将版本号括在单引号或双引号中,而不是<?xml version=1.0?>执行<?xml version="1.0"?><?xml version='1.0'?>。这也可以解释IMO的错误。

XML声明的语法:http://www.w3.org/TR/REC-xml/#NT-XMLDecl

答案 3 :(得分:1)

这可以通过设置自定义参数绑定轻松实现,如下面的博文中所述。我尝试过我的一个项目,我必须使用原始xml帖子进行WebApi

Check this blog entry