gpt4 book ai didi

.net - HttpClient PostAsJsonAsync 在 .NET Core 和 Classic .NET 中的行为不同

转载 作者:行者123 更新时间:2023-12-04 08:41:27 28 4
gpt4 key购买 nike

我在 IIS 中托管了一个 Classic .NET WebAPI 端点,它接受 POST 请求来上传文档。

我创建了两个控制台应用程序,它们将连接到 WebAPI 并上传文档:一个是经典的 .NET (v4.6.2) 控制台应用程序,另一个是 .NET Core 控制台应用程序。代码是相同的,但服务对每个代码的响应不同。 WebAPI 似乎无法读取 .NET Core POST 请求的请求正文,但可以通过 Classic .NET POST 请求读取。

有什么我想念的吗?

WebAPI 端点

http://localhost/WebApi/Library/api/Documents


[Route("api/Documents")]
public class DocumentsController : ApiController
{
[HttpPost()]
public void Create([FromBody] Document document)
{
if (document == null)
{
Debug.WriteLine("Posted document is null.");
}
else
{
Debug.WriteLine($"Document text: {document.Text}");
}
}
}

public class Document
{
public string Text { get; set; }
}

.NET Core/经典 .NET 控制台应用程序
class Program
{
static void Main(string[] args)
{
RunAsAsync().Wait();
}

static async Task RunAsAsync()
{
var httpClient = new HttpClient()
{
BaseAddress = new Uri("http://api-localhost"),
};

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

await httpClient.PostAsJsonAsync("/library/api/documents", new Document() { Text = "The document text" });
}
}

public class Document
{
public string Text { get; set; }
}

事情是这样的:当我将调试器附加到 WebAPI 时,会输出以下内容:

来自经典 .NET 控制台应用程序的 POST 请求:

Document text: The document text



来自 .NET Core 控制台应用程序的 POST 请求:

Posted document is null.



我无法解释行为的差异。

一些额外的信息:

.NET Core 控制台应用程序的 project.json 文件:
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},

"dependencies": {
"Microsoft.AspNet.WebApi.Client": "5.2.3",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
"System.Net.Http": "4.3.0",
"System.Runtime.Serialization.Xml": "4.3.0"

},

"frameworks": {
"netcoreapp1.0": {
"imports": [
"dnxcore50",
"portable-net451+win8"
]
}
}
}

经典的 .NET 包.config:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net462" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net462" />
</packages>

来自 Fiddler 的原始 .NET Core 帖子:
POST http://localhost/library/api/documents HTTP/1.1
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Accept: application/json
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: api-localhost

1c
{"Text":"The document text"}
0

这是原始的经典 .NET POST:
POST http://localhost/library/api/documents HTTP/1.1 Accept:
application/json Content-Type: application/json; charset=utf-8 Host:
api-localhost Content-Length: 28 Expect: 100-continue Connection:
Keep-Alive

{"Text":"The document text"}

在我看来,奇怪的“1c”和“0”可能与我的问题有关。但我不明白他们如何/为什么应该在那里。

更新:一些观察

我还创建了一个非常基本的 .NET Core WebAPI 端点,它基本上与上面描述的 Classic .NET 做同样的事情。这证明能够接受来自两个控制台应用程序的 POST 请求。

我还为 .NET Core 创建了第三个控制台应用程序,我跳过使用 PostAsJsonAsync 而是使用带有 StringContent 的 PostAsync:
public class Program
{
static void Main(string[] args)
{
RunAsAsync().Wait();
}

static async Task RunAsAsync()
{
var httpClient = new HttpClient()
{
BaseAddress = new Uri("http://localhost"),
};

httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var document = new Document() { Text = "The document text." };

var content = JsonConvert.SerializeObject(document);

HttpContent httpContent = new StringContent(content, Encoding.UTF8, "application/json");

await httpClient.PostAsync("/library2/api/documents", httpContent);
}
}

public class Document
{
public string Text { get; set; }
}

在/library/... 和/library2/... 之间交替,来自该应用程序的 POST 请求被 .NET Core 和 Classic .NET WebAPI 接受。

摘要

在服务器端,我有两个 WebAPI
  • /library - 经典 .NET
  • /library2 - .NET Core

  • 在客户端,我有同一个控制台应用程序的三个变体:
  • ConsoleApplication1 - 使用 PostAsJsonAsync 的经典 .NET
  • 适用于两个 WebAPI
  • ConsoleApp1 - .NET Core 使用 PostAsJsonAsync
  • 使用/library(经典 .NET)失败,使用/library2(.NET Core)正常工作
  • ConsoleApp2 - .NET Core 使用 PostAsync
  • 适用于两个 WebAPI

  • 这里明显的解决方法是永远不要在 .NET Core 客户端应用程序中使用 PostAsJsonAsync,这是一种耻辱,因为它真的很方便。 :(

    -S

    最佳答案

    潜在的问题似乎是 Classic .NET WebAPI 无法处理当前最新版本 (v5.2.3) 中的分块请求。我将假设这是一个错误,并作为暂时降级到 v5.0 的解决方法。

    特别感谢@Developer 提供有用的输入。

    -S

    关于.net - HttpClient PostAsJsonAsync 在 .NET Core 和 Classic .NET 中的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42073484/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com