К сожалению, мне не разрешено комментировать, так как моя оценка слишком низкая. Так что просто хотел опубликовать свое расширение отличного топового решения и модификацию для .NET Core 3.0+.
Прежде всего
context.Request.EnableRewind();
был изменен на
context.Request.EnableBuffering();
в .NET Core 3.0+
А вот как я читаю / пишу содержимое тела:
Сначала фильтр, поэтому мы просто изменяем интересующие нас типы контента.
private static readonly IEnumerable<string> validContentTypes = new HashSet<string>() { "text/html", "application/json", "application/javascript" };
Это решение для преобразования надуманных текстов, таких как [[[Translate me]]], в его перевод. Таким образом, я могу просто разметить все, что нужно перевести, прочитать po-файл, который мы получили от переводчика, а затем выполнить замену перевода в выходном потоке - независимо от того, находятся ли тексты с надписями в виде бритвы, javascript или ... что угодно. Вроде как пакет TurquoiseOwl i18n, но в .NET Core, который этот отличный пакет, к сожалению, не поддерживает.
...
if (modifyResponse)
{
//as we replaced the Response.Body with a MemoryStream instance before,
//here we can read/write Response.Body
//containing the data written by middlewares down the pipeline
var contentType = context.Response.ContentType?.ToLower();
contentType = contentType?.Split(';', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(); // Filter out text/html from "text/html; charset=utf-8"
if (validContentTypes.Contains(contentType))
{
using (var streamReader = new StreamReader(context.Response.Body))
{
// Read the body
context.Response.Body.Seek(0, SeekOrigin.Begin);
var responseBody = await streamReader.ReadToEndAsync();
// Replace [[[Bananas]]] with translated texts - or Bananas if a translation is missing
responseBody = NuggetReplacer.ReplaceNuggets(poCatalog, responseBody);
// Create a new stream with the modified body, and reset the content length to match the new stream
var requestContent = new StringContent(responseBody, Encoding.UTF8, contentType);
context.Response.Body = await requestContent.ReadAsStreamAsync();//modified stream
context.Response.ContentLength = context.Response.Body.Length;
}
}
//finally, write modified data to originBody and set it back as Response.Body value
ReturnBody(context.Response, originBody);
}
...
private void ReturnBody(HttpResponse response, Stream originBody)
{
response.Body.Seek(0, SeekOrigin.Begin);
response.Body.CopyToAsync(originBody);
response.Body = originBody;
}
person
Henric Rosvall
schedule
02.03.2020