117 lines
4.3 KiB
C#
117 lines
4.3 KiB
C#
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>();
|
||
}
|
||
}
|
||
} |