我正面临一个奇怪的错误,其中 .NET Core 2.1 API 在某些情况下似乎忽略了 JSON 主体。
- 我建议了许多其他问题(例如this one,它本身引用了其他问题),但无法解决我的问题。
我有类似以下 API 方法的东西:
[Route("api/v1/accounting")]
public class AccountingController
{ sometimes it's null
||
[HttpPost("invoice/{invoiceId}/send")] ||
public async Task<int?> SendInvoice( \/
[FromRoute] int invoiceId, [FromBody] JObject body
)
{
// ...
}
}
而相关的配置是:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services
.AddMvcCore()
.AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new TestJsonConverter());
})
.AddJsonFormatters()
.AddApiExplorer();
// ...
}
TestJsonConverter
我为测试为什么事情不能正常工作而创建的简单转换器在哪里,它很简单:
public class TestJsonConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
return token;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanConvert(Type objectType)
{
return true;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary (would be neccesary if used for serialization)");
}
}
使用 Postman 调用 api 方法是可行的,这意味着它通过 JSON 转换器的CanConvert
, CanRead
, ReadJson
,然后路由到SendInvoice
包含body
解析的 json 的路径。
但是,使用HttpWebRequest调用 api 方法(从 .NET Framework 4,如果这很重要)只会通过CanConvert
,然后路由到SendInvoice
null body
。
请求正文只是一个简单的 json,类似于:
{
"customerId": 1234,
"externalId": 5678
}
当我直接阅读正文时,我得到了两种情况的预期值:
using (var reader = new StreamReader(context.Request.Body))
{
var requestBody = await reader.ReadToEndAsync(); // works
var parsed = JObject.Parse(requestBody);
}
我看不出这两种请求之间有任何有意义的区别——左边是 Postman 的请求,右边是 HttpWebRequest:
可以肯定的是,Content-Type
标题设置为application/json
. 此外,FWIW,HttpWebRequest
正文设置如下:
using(var requestStream = httpWebRequest.GetRequestStream())
{
JsonSerializer.Serialize(payload, requestStream);
}
并调用:
var response = (HttpWebResponse)request.GetResponse();
问题
为什么body
与 一起使用时为空HttpWebRequest
?为什么在这种情况下会跳过 JSON 转换器读取方法?