很遗憾,由于我的分数太低,我无法发表评论。
所以只是想发布我对优秀顶级解决方案的扩展,以及对 .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-file,然后在输出流中进行翻译替换——不管掘金文本是否在剃刀视图中,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;
}