У меня в IIS работает .NET Core Web API. Я хочу добавить тело запроса в журнале IIS на POST. Поэтому в .NET Full Framework я создал библиотеку классов с одним классом, который реализует IHttpModule. Я должен использовать .NET Full Framework, потому что IHttpModule отсутствует в Core.
Моя проблема в том, что запрос InputStream может быть прочитан только один раз. Поэтому, когда я читаю его в своем коде, поток уже в его конце (и объект Stream был изменен с помощью), когда он попадает в мой Core API. Я перепробовал все, что мог придумать, и много искал.
Что не работает:
var bytes = new byte[request.InputStream.Length];
request.InputStream.Read(bytes, 0, bytes.Length);
request.InputStream.Position = 0;
var content = Encoding.UTF8.GetString(bytes);
Да, я получаю тело очень хорошо, но положение потока не сбрасывается. Сброс положения не помогает.
var reader = new StreamReader(HttpContext.Current.Request.InputStream, Encoding.UTF8, true, 1024, true);
HttpContext.Current.Request.InputStream.Position = 0;
Последний флаг должен указывать потоку, чтобы он оставался открытым, но вызов в Ядро все еще не удался.
context.HttpContext.Request.Body
Недоступно в стандартном .NET.
Тогда я попробовал это:
var s2 = new MemoryStream(request.TotalBytes);
HttpContext.Current.Request.InputStream.CopyTo(s2);
По-прежнему не удается. Даже этот небольшой код делает его неудачным:
var v = request.TotalBytes;
Мои мысли пока
Глядя на исходный код потока, я вижу, что некоторые его внутренние данные изменяются при чтении свойств, поэтому я думаю, что это IIS, проверяющий, что сообщение не было подделано перед его отправкой Кестрелу. Может кто-нибудь пролить некоторый свет на это? Может быть, вы знаете, кто-то другой выполняет эту задачу?
Примечание: Да, я могу вывести тело сообщения другими способами, используя другие модули IIS, но они не помещают его в стандартный журнал IIS, они создают свои собственные. Я уже использую журнал IIS в стек ELK, поэтому так будет проще.