웹 API 요청 콘텐츠 (예 : json 문자열)를 로그 아웃하려고합니다. ITraceWriter 클래스 (example)를 구현하고이를 웹 API가 파이프 라인에서 호출하도록 구성했습니다. 그러나 요청을 읽으면 내용을 읽거나 스트림으로 복사하여 null 모델이되는 메서드에 사용할 수 없습니다. This post 그 문제에 대해 조금 이야기합니다. 누구나 인바운드 웹 API 요청 콘텐츠를 로깅 한 경험이 있으며 최상의 접근 방식이 무엇인지 알고 있습니까?ASP.NET 웹 API 인바운드 요청 내용 로깅
감사
업데이트는
나는 내 프로젝트에서 어떤 것도 배제하는 간단한 샘플 웹 API 프로젝트를 생성하고 난 여전히 모델 때문에 로깅 null이 될 것입니다 것을 알 수있다. 나는 Fidder를 통해 게시하여 몇 번 연속 테스트하고 내 모델이 null로 표시되는지 확인합니다. 중단 점이 제자리에 있으면 작동 할 수도 있기 때문에 동기/타이밍 문제가 있다고 생각합니다. 이 방법을 사용하는 방법에 대한 의견이 있으십니까?
헤더 :
User-Agent: Fiddler
Host: localhost:56824
Content-Type: application/json
Content-Length: 22
바디 :
컨트롤러 :
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!");
}
}
}
모델 :
0 여기{
"A":1,"B":"test"
}
코드입니다
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;
}
}
Filip에 의해 그 주석에 의해 던졌습니다. 내가 ReadAsStringAsync를 사용하고 내 모델이 null이 될 것입니다. ITraceWriter 구현에서 사용한 기본 코드는 다음과 같습니다. request.Content.ReadAsStringAsync(). ContinueWith (s => { string requestText = s.Result; Logger.Log (requestText); }}); – Bryan
당신이 언급 한 문제를 재현 할 수 없습니다. 예를 들어 (최선의 방법은 아닙니다), Mike Wasson의 샘플에서 SimpleTracer의 WriteTrace 메서드에 다음 코드가 있습니다. if (rec.Request! = null) {Console.WriteLine (rec.Category + ","+ rec.Request.Content.ReadAsStringAsync(). 결과); } –
다시 해봐 줘서 고마워. 무엇이 다른지 알아 내려고하는 중입니다. 내 로컬 dev에 대한 MVC 4 및 IIS Express에서 실행중인 사용하고 있습니다. 아마 IIS Express가 그 차이 일 것입니다. 나는 다른 것을 시도하고 다시 게시 할 것입니다. – Bryan