.net8通用中间件处理公共返回值结构

using Microsoft.AspNetCore.Http;
using System;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;

public class ApiResponseMiddleware
{
    private readonly RequestDelegate _next;

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

    public async Task Invoke(HttpContext context)
    {
        if (context.GetEndpoint()?.Metadata?.GetMetadata<SignalREndpointAttribute>() != null)
        {
            await _next(context);
            return;
        }

        var originalBody = context.Response.Body;
        using var memoryStream = new MemoryStream();
        context.Response.Body = memoryStream;

        ApiResponse result = null;
        var statusCode = 200;

        try
        {
            await _next(context);
            memoryStream.Position = 0;

            if (context.Response.StatusCode == 200)
            {
                if (memoryStream.Length > 0)
                {
                    context.Response.Body = originalBody;
                    context.Response.ContentLength = memoryStream.Length;
                    await memoryStream.CopyToAsync(originalBody);
                    return;
                }
                else
                {
                    result = ApiResponse.Success;
                }
            }
            else
            {
                statusCode = context.Response.StatusCode;
                result = ApiResponse.Fail(statusCode, statusCode.ToString());
            }
        }
        catch (Exception ex)
        {
            var exception = ex.InnerException ?? ex;
            result = BuildErrorResponse(exception, 200);
        }

        context.Response.Clear();
        context.Response.Body = originalBody;
        context.Response.StatusCode = statusCode;
        await context.Response.WriteAsJsonAsync(result, result.GetType(), new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = false
        });
    }

    private static ApiResponse BuildErrorResponse(Exception exception, int statusCode)
    {
        if (exception is LevelException levelEx)
        {
            var exConfig = LevelExceptionConfig.GetConfig(levelEx);
            return ApiResponse.Fail((int)ErrorLevel.LangageInfo, levelEx.Message, exConfig);
        }
        return ApiResponse.Fail(statusCode, exception.Message);
    }
}

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class SignalREndpointAttribute : Attribute { }

public class ApiResponse
{
    public int Code { get; set; }
    public string Message { get; set; }
    public object Data { get; set; }

    public static ApiResponse Success => new ApiResponse { Code = 0, Message = "success" };

    public static ApiResponse Fail(int code, string message, object data = null)
    {
        return new ApiResponse { Code = code, Message = message, Data = data };
    }
}

public class LevelException : Exception
{
    public LevelException(string message) : base(message) { }
    public LevelException(string message, Exception inner) : base(message, inner) { }
}

public class LevelExceptionConfig
{
    public string Detail { get; set; }

    public static LevelExceptionConfig GetConfig(LevelException ex)
    {
        return new LevelExceptionConfig { Detail = $"Exception: {ex.Message}" };
    }
}

public enum ErrorLevel
{
    LangageInfo = 1000
}
posted @ 2026-07-27 18:37  Hey,Coder!  阅读(5)  评论(0)    收藏  举报