从Body of WebAPI调用中读取XML内容在开始时被截断

atc*_*way 6 c# http-post asp.net-web-api dotnet-httpclient

我正在创建一种代理服务,需要处理包含XML的调用POST到我的WebAPI服务的主体,然后再POST处理到另一个服务.

奇怪的是当我POST从身体的XML的第一部分收到XML消息时被切断了.最初我认为可能是缓冲区大小,或者消息太大,所以我删除了大量发送的XML测试消息,减少了发送的内容.然而,XML 仍然在同一个地方被切断.

我尝试了以下(2)方法来读取WebAPI服务中的XML BODY,结果是一样的:

var reader = new StreamReader(Request.Content.ReadAsStreamAsync().Result);
string originalMessage = reader.ReadToEnd();
Run Code Online (Sandbox Code Playgroud)

和:

        var result = "";
        Request.Content.ReadAsStreamAsync().ContinueWith(x =>
        {

            using (var sr = new StreamReader(x.Result))
            {
                result = sr.ReadToEnd();
            }
        });
Run Code Online (Sandbox Code Playgroud)

这是原始XML的片段:

<Message version="123" release="001" xmlns="http://www.mysite.com/schema">
  <Header>
    <To Att1="A">001</To>
    <From Att2="B">002</From>
    <ID>9876</ID>
Run Code Online (Sandbox Code Playgroud)

以下是在WebAPI控制器中读取内容后的内容的开头POST:

</To>
    <From Att2="B">002</From>
    <ID>9876</ID>
Run Code Online (Sandbox Code Playgroud)

看看它是如何从<To>元素的"结束"标签开始的?这显然不是它发送的XML的开始.

更奇特的是在发送之前检查的"内容大小"以及在两侧之后是4188.还有一件有趣的事情是,我有一个老式的时尚.asmx测试器(而不是Web API服务)可以做同样的事情.当我使用以下内容读取该应用程序中的传入XML消息时:

    // Get raw request body
    Stream receiveStream = HttpContext.Current.Request.InputStream;

    // Move to beginning of input stream and read
    receiveStream.Position = 0;
    using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
    {
    // Load into XML document
    xmlSoapRequest.Load(readStream);
    }
Run Code Online (Sandbox Code Playgroud)

...我看到了完整的 XML消息.所以不确定为什么.asmx可以完全阅读它而不是WebAPI服务.

在我的WebAPI POST调用中,我无法看到在请求正文中发送的完整XML消息,我做错了什么?

atc*_*way 11

好吧,我想出了问题,但并不是100%肯定的原因.我正在使用的参数是POST开箱即用的参数:

public HttpResponseMessage Post([FromBody]string value)
Run Code Online (Sandbox Code Playgroud)

我更改了它以将请求作为参数POST取而代之:

public HttpResponseMessage Post(HttpRequestMessage request)
Run Code Online (Sandbox Code Playgroud)

当我执行上面的第二个选项时,我开始按预期从请求中获取整个XML正文.

  • 第一个方法签名使Web API使用当前配置的XML Serializer来尝试将消息反序列化为"String"对象,这根本不是您想要做的.第二种方法更有意义,因为您没有尝试通过线路序列化对象. (5认同)