如果使用 FromBody 和 FromForm 参数始终为 null/new,则对 Core API 的 Webclient 调用找不到端点

Webclient call to Core API can't find endpoint if using FromBody and FromForm parameter is always null/new

这是 API 代码片段:

[HttpPost]
[ProducesResponseType(typeof(myObject), 201)] //created
[ProducesResponseType(500)] //server error
public IActionResult Create([FromForm]myObject myObj) {
...

这是服务器端调用:

...
using (WebClient client = new WebClient()) {        
    NameValueCollection formData = new NameValueCollection();
    string targetURL = "https://localhost:44317/api/MyController/Create"
    string callMethod = "POST";
    formData["myObj"] = JsonConvert.SerializeObject(myObj);
    var thingy = client.UploadValues(targetURL, callMethod, formData);
    ...

如果我使用 [FromForm],调用会找到端点,但传入的数据就像我说的 myObj = new MyObject(); 一样,所有内容都具有默认值。所以... 完全 不为空。

如果我使用 [FromBody]client 找不到 url,我得到一个 400 Bad Request

我已经阅读了这里和其他地方的大量帖子,但我认为它们并没有完全涵盖这种情况,因为我观察到的似乎与其他人的要求相反。所以我不确定我的代码发生了什么。

请注意,我不能使用 async,所以我不能使用 HttpClient。 (不能使用异步,因为这是 Kentico 站点内部,这是门户页面内部的 ascx)

你的 FromForm 问题是你将它序列化为字符串,默认情况下 WebAPI 不会为你反序列化它。如果你想继续 FromForm 你可以将参数类型更改为字符串并显式反序列化它:

public IActionResult Create([FromForm]string myObj) {
    myObject obj = JsonConvert.DeserializeObject<myObject>(myObj);
    ...

看起来你打算 post JSON,但你实际上 posting 作为 x-www-form-urlencoded 序列化的 JSON 作为值对于 myObj 参数。由于编码类型的原因,该操作必须使用 [FromForm](或根本没有属性),但此时它无法将您的 "JSON" 反序列化为对象。我在这里用引号括起 "JSON" 因为实际上它只是一个字符串。 ASP.NET Core 根本不知道这甚至是 JSON,也不应该对它做些什么。总之,您需要 post 一个实际的 application/json 请求正文。

using (var client = new WebClient())
{
    client.Headers["Content-Type"] = "application/json; charset=utf-8";
    var requestBody = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(myObj));
    var response = webClient.UploadData(targetUrl, callMethod, requestBody);
}

然后,当然,您需要在参数上实际使用 FromBody 属性,因为现在您实际上会收到 JSON.