C# WebClient 使用 UploadString 从 ApiController 调用 HttpPost 方法也在 C# 中。 415 或 400 错误

Posted

技术标签:

【中文标题】C# WebClient 使用 UploadString 从 ApiController 调用 HttpPost 方法也在 C# 中。 415 或 400 错误【英文标题】:C# WebClient using UploadString to call HttpPost method from an ApiController also in C#. 415 or 400 error 【发布时间】:2019-09-15 03:20:25 【问题描述】:

我希望在 C# 中也可以在 C# 中调用 ApiController,但是在使用 WebClient 实例中的 UploadString 方法上传 Json 时出现错误 415 或 400。

服务器代码是自动生成的调用TestController。该文件正是 Visual Studio 2019 生成它的方式。

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase

    // GET: api/Test
    [HttpGet]
    public IEnumerable<string> Get()
    
        return new string[]  "value1", "value2" ;
    

    // POST: api/Test
    [HttpPost]
    public void Post([FromBody] string value)
    
    
    ...

客户端代码如下所示:

WebClient client = new WebClient();
client.UploadString("https://localhost:44345/api/Test", "ABC");   // Edit: "ABC" is not a valid JSON

我得到 System.Net.WebException: '远程服务器返回错误:(415) Unsupported Media Type.'

所以谷歌搜索后,大多数建议是 ContentType 没有得到指定,如果我添加

client.Headers[HttpRequestHeader.ContentType] = "application/json";

我得到 System.Net.WebException: '远程服务器返回错误:(400) Bad Request.'

有什么线索吗?

似乎问题与POST/PUT/PATCH有关...如果我执行GET,它正在工作并返回样本数据["value1","value2"]

编辑:我不坚持使用 WebClient.UploadString 方法,但我想要一个不涉及 25 行自定义代码的解决方案......我的意思是我不敢相信你能做到的这么难在 jQuery 中使用单行。

【问题讨论】:

【参考方案1】:

我得到 System.Net.WebException: '远程服务器返回错误:(415) Unsupported Media Type.'

当您使用[FromBody] 时,Content-Type 标头用于确定如何解析请求正文。如果未指定Content-Type,则模型绑定过程不知道如何使用主体,因此返回 415。

我得到 System.Net.WebException: '远程服务器返回错误:(400) Bad Request.'

通过将Content-Type 标头设置为application/json,您指示模型绑定过程将数据视为JSON,但ABC 本身不是有效的JSON。如果你只是想发送一个 JSON 编码的字符串,你也可以将值用引号括起来,像这样:

client.UploadString("https://localhost:44345/api/Test", "\"ABC\"");

"ABC" 是一个有效的 JSON 字符串,将被您的 ASP.NET Core API 接受。

【讨论】:

【参考方案2】:

简单的解决方案:

在调用 API 时在 header 中指定 Content-type

            WebClient client = new WebClient();
            client.Headers.Add("Content-Type", "text/json");
            client.UploadString("https://localhost:44345/api/Test", "\"ABC\"");

编辑:

不要使用[From_Body] 属性,因为它具有糟糕的错误处理能力, 见Here。

如果请求正文有任何无效输入(语法错误,不支持的输入),那么它将抛出 400415 用于错误请求和不支持的内容。出于同样的原因,它可能会将 null 作为请求正文的输入,因为它不理解格式。

因此,请删除该属性并尝试以纯格式上传字符串,因为它只接受字符串,并且您在发出请求时不需要指定 Content-Type 属性。

[HttpPost]
 public void Post(string value)
 

 

并像您在原始帖子中那样称呼它。

WebClient client = new WebClient();
client.UploadString("https://localhost:44345/api/Test", "ABC");

【讨论】:

感谢您的回复,我确实删除了 [From_Body],我没有收到任何异常,但该值始终为 null。我尝试过指定或不指定 Content-type。 我创建了一个类似于您的模拟应用程序并正确获取数据,我不确定是什么导致了您的错误。 :(

以上是关于C# WebClient 使用 UploadString 从 ApiController 调用 HttpPost 方法也在 C# 中。 415 或 400 错误的主要内容,如果未能解决你的问题,请参考以下文章

C# WebClient 禁用缓存

使用 WebClient C# 添加请求标头

使用 C# Windows Forms 和 webclient 下载文件

[C#]使用WebClient上传文件并同时Post表单数据字段到服务端

C# WebClient - 从 URI 获取 HTML 而不是从 OBIEE 获取 CSV

C#使用WebClient与WebRequest有啥不同