我试图通过httpclient发布匿名对象,但是当命中控制器时,orderId为null且集合为空。
public async Task<Response> CancelOrderAsync(int orderId, ICollection<int> ids)
{
Response result = null;
using (IHttpClient client = HttpClientFactory.CreateHttpClient())
{
var obj = new {OrderId = orderId, Ids = ids};
string json = JsonConvert.SerializeObject(obj);
HttpContent postContent = new StringContent(json, Encoding.UTF8, "application/json");
using (var response = await client.PostAsync($"{url}/admin/cancel", postContent).ConfigureAwait(false))
{
if (response != null && response.IsSuccessStatusCode)
{
...
}
}
}
return result;
}
// Controller
[HttpPost]
[ActionName("cancel")]
public async Task<Response> Cancel(int orderId, ICollection<int> ids)
{
// order is null, collection empty
...
编辑:
为简单起见,将我的控制器更改为此
[HttpPost]
[ActionName("cancel")]
public async Task<SimpleResponse> Cancel(int orderId)
通过Postman,我发布了这个机构:
{
"orderId": "12345"
}
仍然,orderId为0(零)??
答案 0 :(得分:3)
服务器端的控制器操作需要具体类型来读取请求的整个主体
public class Order {
public int OrderId { get; set; }
public int[] Ids { get; set; }
}
这主要是因为动作只能从身体上读取一次。
将行动更新为......
[HttpPost]
[ActionName("cancel")]
public async Task<Response> Cancel([FromBody]Order order) {
if(ModelState.IsValid) {
int orderId = order.OrderId;
int[] ids = order.Ids;
//...
}
//...
}
用于在示例中发送请求的原始代码将按原样运行,但如上所述,它可以进行改进。
答案 1 :(得分:1)
HttpClient可以为您进行序列化。看看
var response = await client.PostAsJsonAsync($"{url}/admin/cancel", obj);
效果更好。那你就不需要自己编写序列化代码了。
如果您仍有问题,请使用Fiddler等工具监控实际请求,并查看请求正文中提交的参数和值,以查看它们是否与端点的预期相符。