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
{
///
/// 响应格式化中间件
///
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() is ControllerActionDescriptor actionDescriptor)
{
var messageAttribute = actionDescriptor.MethodInfo.GetCustomAttribute();
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
{
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;
}
}
}
///
/// 中间件扩展方法
///
public static class ResponseFormatterMiddlewareExtensions
{
public static IApplicationBuilder UseResponseFormatter(this IApplicationBuilder builder)
{
return builder.UseMiddleware();
}
}
}