Web APIリクエストコンテンツ(つまり、json文字列)をログアウトしようとしています。ITraceWriterクラス(例)を実装し、WebAPIがパイプラインで呼び出すように構成しました。しかし、request.Contentを読み取ったり、ストリームにコピーして読み取ったりすると、メソッドで使用できなくなり、モデルがnullになります。 この投稿では、その問題について少し説明しています。インバウンドWebAPIリクエストコンテンツをログアウトした経験があり、最善のアプローチを知っている人はいますか?
ありがとう
アップデートA
プロジェクト内のすべてを除外するために、単純なサンプルWeb APIプロジェクトを作成しましたが、ロギングのためにモデルがnullになることがわかります。Fidderを介して投稿することにより、連続して数回テストするだけで、モデルがnullになることを確認します。ブレークポイントを設定すると、機能する可能性があります。そのため、同期/タイミングの問題があると思います。これを機能させる方法について何か考えはありますか?
ヘッダ:
User-Agent: Fiddler
Host: localhost:56824
Content-Type: application/json
Content-Length: 22
体:
{
"A":1,"B":"test"
}
コードは次のとおりです。
コントローラ:
public class ValuesController : ApiController
{
[HttpPost]
public void Post(ValuesModel model)
{
if (model == null)
{
Debug.WriteLine("model was null!");
}
else
{
Debug.WriteLine("model was NOT null!");
}
}
}
モデル:
public class ValuesModel
{
public int A { get; set; }
public string B { get; set; }
}
ロガー:
public class APITraceLogger : DelegatingHandler
{
protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
if (request.Content != null)
{
// This can cause model to be null
request.Content.ReadAsStringAsync().ContinueWith(s =>
{
string requestText = s.Result;
Debug.WriteLine(requestText);
});
// and so can this
//request.Content.ReadAsByteArrayAsync()
// .ContinueWith((task) =>
// {
// string requestText = System.Text.UTF8Encoding.UTF8.GetString(task.Result);
// Debug.WriteLine(requestText);
// });
}
// Execute the request, this does not block
var response = base.SendAsync(request, cancellationToken);
// TODO:
// Once the response is processed asynchronously, log the response data
// to the database
return response;
}
}
WebApiConfigクラスでのロガーの配線:
config.MessageHandlers.Add(new APITraceLogger());
アップデートB
ロガーを次のコードに変更してawait、asyncを追加し、結果を返すと、現在は機能しているようです。非同期コードで理解していないことや、本当にタイミングの問題などのようです。
public class APITraceLogger : DelegatingHandler
{
protected async override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
if (request.Content != null)
{
// This does seem to work - is it because it is synchronous? Is this a potential problem?
var requestText = await request.Content.ReadAsStringAsync();
Debug.WriteLine(requestText);
}
// Execute the request, this does not block
var response = base.SendAsync(request, cancellationToken);
// TODO:
// Once the response is processed asynchronously, log the response data
// to the database
return response.Result;
}
}