Capturar cru HTTP POST dados durante Exceção
-
05-09-2019 - |
Pergunta
Eu tenho um serviço WCF hospedado no IIS / ASP.NET que aceita HTTP Post ( não formar pós ) de objetos serializados.
Se o cliente envia pedidos mal formados (por exemplo, eles não estão a serialização do objeto corretamente) eu gostaria de registrar a mensagem enviada para cima.
Já estamos usando ELMAH para capturar exceções não tratadas, tão simplesmente anexando os dados post seria a opção mais fácil.
posso obter o atual HttpContext durante uma exceção, no entanto, este não contém apenas as informações de cabeçalho HTTP.
A minha pergunta é esta: Existe alguma maneira de capturar o corpo original solicitação HTTP POST? Ou, na sua falta - uma maneira melhor (sem um proxy reverso) de capturar a entrada que causou o erro?
Edit: Só para esclarecer, correndo captura de nível pacote em todos os tempos não é realmente adequado. Eu estou atrás de uma solução que eu posso implantar em servidores de produção, e que terá clientes fora do nosso controlo ou capacidade de monitorar.
Edit # 2: A sugestão foi feita para o acesso a Request.InputStream - isso não funciona se você estiver tentando ler depois WCF tem ler a solicitação fora do fluxo.
A peça de amostra de código para ver como eu tentei usar isso está aqui.
StringBuilder log = new StringBuilder();
var request = HttpContext.Current.Request;
if (request.InputStream != null)
{
log.AppendLine(string.Format("request.InputStream.Position = \"{0}\"", request.InputStream.Position));
if (request.InputStream.Position != 0)
{
request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
}
using (StreamReader sr = new StreamReader(request.InputStream))
{
log.AppendLine(string.Format("Original Input: \"{0}\"", sr.ReadToEnd()));
}
}
else
{
log.AppendLine("request.Inputstream = null");
}
log.ToString();
O ouput de log.ToString () é:
request.InputStream.Position = "0" Original Input: ""
Solução
No momento em que ele chegue ao seu serviço o pedido é processado e não está disponível para você.
No entanto ... você pode anexar um mensagem inspetor . Inspetores de mensagens permitem que você mexer com a mensagem antes que ele atinja suas implementações de operação. Você pode criar uma cópia em buffer da mensagem, e copiá-lo para o OperationContext.Current.
gambiarra é claro, e isso significará sobrecarga de memória como agora duas cópias da mensagem estão flutuando sobre para cada solicitação.
Outras dicas
Será que você olha para a propriedade System.Web.Request.InputStream? Ela deve ter exatamente o que você quer.
Como "rebobinar" a propriedade InputStream.
if (Request.InputStream.Position != 0)
{
Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
}
Outra opção que você deve olhar para é capturar essa informação com um HttpModule no evento BeginRequest. Os dados devem estar lá no evento BeginRequest, porque eu não acredito WCF pega o pedido até depois PostAuthenticateEvent.
debaixo ASP.NET (serviço de web ASP no IIS) o seguinte código ajuda:
if (request.InputStream.Position != 0)
{
request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
}
WCF talvez diferente (que é Dispõe InputStream após a leitura)
Use violinista. Livre de MS. Funciona muito bem.