特定のケースで .NET Core 2.1 API が JSON 本体を無視しているように見える奇妙なバグに直面しています。
- 他にも多くの質問にアドバイスしましたが (たとえば、これ自体が他のものを参照しています)、問題を解決できませんでした。
次の 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)");
}
}
CanConvert
Postman を使用した api メソッドの呼び出しは機能します。つまり、JSON コンバーターの、CanRead
、を通過し、解析された jsonを含むReadJson
にルーティングされます。SendInvoice
body
ただし、 HttpWebRequestを使用して api メソッドを呼び出すと(問題がある場合は .NET Framework 4 から)のみが通過しCanConvert
、 nullにルーティングさSendInvoice
れます。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);
}
2 種類のリクエストに意味のある違いは見当たりません。左側は Postman のリクエスト、右側は HttpWebRequest です。
確かに、Content-Type
ヘッダーは に設定されていapplication/json
ます。また、FWIW、HttpWebRequest
本体は次のように設定されています。
using(var requestStream = httpWebRequest.GetRequestStream())
{
JsonSerializer.Serialize(payload, requestStream);
}
そして、次のように呼び出します。
var response = (HttpWebResponse)request.GetResponse();
質問
body
で使用すると null になるのはなぜHttpWebRequest
ですか? このような場合、JSON コンバーターの読み取りメソッドがスキップされるのはなぜですか?