ChouBox/ChouBox.WebApi/Middleware/ResponseFormatterMiddleware.cs
2025-04-23 19:20:23 +08:00

117 lines
4.3 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using HuanMeng.DotNetCore.AttributeExtend;
using HuanMeng.DotNetCore.Base;
using HuanMeng.DotNetCore.Extensions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
namespace ChouBox.WebApi.Middleware
{
/// <summary>
/// 响应格式化中间件
/// </summary>
public class ResponseFormatterMiddleware
{
private readonly RequestDelegate _next;
public ResponseFormatterMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// 保存原始响应流
var originalBodyStream = context.Response.Body;
try
{
// 使用内存流替代响应流
using var memoryStream = new MemoryStream();
context.Response.Body = memoryStream;
// 继续处理请求
await _next(context);
// 获取可能存在的动态消息从HTTP头部
string customMessage = context.GetDynamicMessage();
// 如果没有动态消息则检查MessageAttribute
if (string.IsNullOrEmpty(customMessage))
{
var endpoint = context.GetEndpoint();
if (endpoint != null)
{
if (endpoint.Metadata.GetMetadata<ControllerActionDescriptor>() is ControllerActionDescriptor actionDescriptor)
{
var messageAttribute = actionDescriptor.MethodInfo.GetCustomAttribute<MessageAttribute>();
if (messageAttribute != null)
{
customMessage = messageAttribute.Message;
}
}
}
}
// 如果是API接口请求并且内容类型是JSON
if (context.Request.Path.StartsWithSegments("/api") &&
context.Response.ContentType != null &&
context.Response.ContentType.Contains("application/json"))
{
memoryStream.Seek(0, SeekOrigin.Begin);
string responseBody = await new StreamReader(memoryStream).ReadToEndAsync();
// 如果响应内容是简单字符串(不是JSON格式)将其包装成BaseResponse
if (!string.IsNullOrEmpty(responseBody) &&
!responseBody.StartsWith("{") &&
!responseBody.StartsWith("["))
{
var response = new BaseResponse<string>
{
Status = 1,
Msg = customMessage,
Data = responseBody.Trim('"') // 去除JSON序列化添加的引号
};
// 重置流
memoryStream.SetLength(0);
// 写入格式化后的响应
using var writer = new StreamWriter(memoryStream, leaveOpen: true);
await writer.WriteAsync(response.ToString());
await writer.FlushAsync();
// 更新Content-Length
context.Response.ContentLength = memoryStream.Length;
}
}
// 将内存流复制回原始响应流
memoryStream.Seek(0, SeekOrigin.Begin);
await memoryStream.CopyToAsync(originalBodyStream);
}
finally
{
// 恢复原始响应流
context.Response.Body = originalBodyStream;
}
}
}
/// <summary>
/// 中间件扩展方法
/// </summary>
public static class ResponseFormatterMiddlewareExtensions
{
public static IApplicationBuilder UseResponseFormatter(this IApplicationBuilder builder)
{
return builder.UseMiddleware<ResponseFormatterMiddleware>();
}
}
}