这是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
找不到该网址,而我得到一个400 Bad Request
。
我想在这里和其他地方都读过很多文章,我认为它们并不能完全涵盖这种情况,因为我观察到的内容似乎与其他人的要求相反。所以我不太确定我的代码是怎么回事。
请注意,我无法使用 async ,因此无法使用HttpClient。 (不能使用异步,因为它位于Kentico站点内,并且是门户页面内的ascx)
答案 0 :(得分:1)
似乎您打算发布JSON,但实际上您是以x-www-form-urlencoded
的形式发布的,其中已序列化的JSON作为myObj
参数的值。由于编码类型的原因,该操作必须使用[FromForm]
(或完全不使用属性),但是到那时,它不能将您的“ JSON”反序列化为一个对象。我在这里在引号中使用“ JSON”,因为实际上这只是一个字符串。 ASP.NET Core甚至不知道这甚至是JSON,也不知道应该对此做些什么。总而言之,您需要发布一个实际的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。
答案 1 :(得分:0)
FromForm
的问题在于,您将其序列化为字符串,并且WebAPI在默认情况下不会为您反序列化。如果要继续使用FromForm
,可以将参数类型更改为string并对其进行显式反序列化:
public IActionResult Create([FromForm]string myObj) {
myObject obj = JsonConvert.DeserializeObject<myObject>(myObj);
...