简书链接:webapicore全局拦截200的结果进行文本替换等逻辑操作办法
文章字数:243,阅读全文大约需要1分钟
方法1 中间件实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

public class TextReplaceMiddleware
{
private readonly RequestDelegate _next;

public TextReplaceMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task InvokeAsync(HttpContext context)
{
// 暂存原始响应内容
var originalBodyStream = context.Response.Body;
using (var responseBody = new MemoryStream())
{
// 替换响应内容
context.Response.Body = responseBody;

await _next(context);

// 恢复原始响应内容
context.Response.Body.Seek(0, SeekOrigin.Begin);
var body = await new StreamReader(context.Response.Body).ReadToEndAsync();
body = body.Replace("oldText", "newText");
context.Response.Body.Seek(0, SeekOrigin.Begin);

// 将修改后的响应内容写回原始响应流中
await context.Response.Body.WriteAsync(Encoding.UTF8.GetBytes(body));
context.Response.Body = originalBodyStream;
}
}
}

1
2
3
4
5
6
7
8
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...

app.UseMiddleware<TextReplaceMiddleware>();

// ...
}

方法2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;

public class TextReplaceFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var resultContext = await next();

// 判断响应是否为200
if (resultContext.HttpContext.Response.StatusCode == 200)
{
// 暂存原始响应内容
var originalBodyStream = resultContext.HttpContext.Response.Body;
using (var responseBody = new MemoryStream())
{
// 替换响应内容
resultContext.HttpContext.Response.Body = responseBody;

// 读取响应内容并替换
var body = await new StreamReader(originalBodyStream).ReadToEndAsync();
body = body.Replace("oldText", "newText");

// 将修改后的响应内容写回原始响应流中
await resultContext.HttpContext.Response.Body.WriteAsync(Encoding.UTF8.GetBytes(body));
resultContext.HttpContext.Response.Body = originalBodyStream;
}
}
}
}

调整controller

1
2
3
4
5
[ServiceFilter(typeof(TextReplaceFilter))]
public class MyController : ControllerBase
{
// ...
}

另外

1
2
3

//builder.Services.AddSingleton<CollectAlertActionFilter>();//单例
builder.Services.AddScoped<CollectAlertActionFilter>();

还有一些坑,kenel需要禁用缓冲区最后换了一种办法

1
2
3
4
5
6
7
8
9
10
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var resultContext = await next();

if (resultContext.Result is ObjectResult objectResult)
{
var response = context.HttpContext.Response;
if (objectResult.StatusCode == 200|| response.StatusCode==200)
{
var responseString = objectResult.Value.ToString();

```是空的所以还是用之前的那种判断
1
2

获取controller
                    var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
                    var controllerName = actionDescriptor?.ControllerName;
                    var actionName = actionDescriptor?.ActionName;

                    // 获取Controller的描述信息
                    var controllerType = actionDescriptor?.ControllerTypeInfo.AsType();
                    var controllerName1 = context.RouteData.Values["controller"];
                    var actionName1 = context.RouteData.Values["action"];
1
2
获取displayName
经过测试 发现里面有多个displayname,默认的也存在,根据条件进行过滤吧
   DisplayNameAttribute displayName = context.ActionDescriptor.GetProperty<DisplayNameAttribute>();
                    methodDescriptor= actionDescriptor.MethodInfo.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName;
                    var displayNameAttribute = context.ActionDescriptor.EndpointMetadata
      .OfType<DisplayNameAttribute>()
      .LastOrDefault()?.DisplayName;