12

这是这个问题的一个分支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>

...我收到异常:“ System.Xml.XmlException 未被用户代码 HResult=-2146232000 Message=Root 元素处理。

使用此代码(相同的 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 c:\HandheldServer\HandheldServer\Controllers\DeliveryItemsController.cs 中的 .MoveNext():第 109 行 InnerException:

IOW,根据我解析传入字符串的方式,我得到“缺少根元素”或“序列不包含元素

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

我是否需要在无法使用的情况下手动将 XML 拆开XDocument

注意:从 Fiddler 发送正文数据(XML 文本)有效(我发送的内容如我所愿);但即便如此,服务器上的 XML 解析代码也会失败。

但是,尝试从手持/紧凑型框架客户端代码发送相同的数据,只会导致数据通过“=”(类似于<xml version="传递到服务器;然后在客户端上,我看到“无法执行此操作提交请求后

更新

因此,根据 Marcin 的回答,如果我坚持使用 XDocument.Parse() 我应该没问题,并且根据 TToni 的回答,数据/xml 本身可能很糟糕。这是文件的内容:

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

所以版本号周围有引号 - 但我是否需要以某种方式转义 - 这就是数据被截断的原因 - 因为当它看到第一个引号(“1.0”之前)时,它认为这是字符串终止,也许?

更新 2

Marcin,传入的“xml”数据(字符串)在到达 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 的建议并用单引号替换双引号:

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

在此处输入图像描述

...但我仍然收到“缺少根元素”:

System.Xml.XmlException 未被用户代码处理 HResult=-2146232000 消息=缺少根元素。Source=System.Xml LineNumber=0 LinePosition=0 SourceUri="" StackTrace: 在 System.Xml.XmlTextReaderImpl.Throw(Exception e) 在 System.Xml.XmlTextReaderImpl.ParseDocumentContent() 在 System.Xml.XmlTextReaderImpl.Read() 在System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options) 在 System.Xml.Linq.XDocument.Load(Stream stream, LoadOptions options) 在 System.Xml.Linq.XDocument.Load(Stream stream) 在 HandheldServer。 c:\HandheldServer\HandheldServer\Controllers\DeliveryItemsController.cs:line 66 InnerException 中的 Controllers.DeliveryItemsController.d__2.MoveNext():

如果我还没有发疯,这会让我发疯。事实上,我不太清楚自己被驱赶到哪里。许多雇主正在寻找有动力的人。也许这就是他们的意思?

更新 4

使用这个:

XDocument doc = XDocument.Parse(stringifiedXML);

...而不是这个:

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

...解决了“缺少根元素”错误消息;因此,我将 Marcin 的答案标记为正确。

4

4 回答 4

17

对于那些通过谷歌找到这个页面,但仍然感到困惑的人。我相信我已经找到了答案,这要归功于埋藏的 MS Post

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

xmlStream.Seek(0, SeekOrigin.Begin);

如果在读取之前没有这个,您实际上是在流的末尾开始加载。没有根元素,因为没有更多的流。

于 2015-10-26T15:46:42.243 回答
8

您提供的示例 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()返回您需要的东西。

于 2014-03-14T21:53:53.560 回答
2

如果那真的是您的字符串化 XML,那么您的 XML 声明就被破坏了。您需要将版本号括在单引号或双引号中,因此不要使用<?xml version=1.0?>do<?xml version="1.0"?><?xml version='1.0'?>. 这也可以解释国际海事组织的错误。

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

于 2014-03-14T21:58:15.023 回答
1

这可以通过设置自定义参数绑定来轻松实现,如下面的博客文章中所述。我在我的一个项目中尝试过,我不得不为 WebApi 使用原始 xml 帖子

检查此博客条目

于 2018-03-09T17:29:06.500 回答