You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
5.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace Haoliang.Core.Services
{
// 中间件和过滤器
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionMiddleware> _logger;
public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex, "An unhandled exception occurred");
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
context.Response.ContentType = "application/json";
var response = new
{
success = false,
message = "Internal server error",
timestamp = DateTime.Now,
error = exception.Message
};
context.Response.StatusCode = 500;
return context.Response.WriteAsJsonAsync(response);
}
}
public class LoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<LoggingMiddleware> _logger;
public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var startTime = DateTime.Now;
// 记录请求信息
_logger.LogInformation($"Request: {context.Request.Method} {context.Request.Path}");
try
{
await _next(context);
}
finally
{
var duration = DateTime.Now - startTime;
_logger.LogInformation($"Response: {context.Response.StatusCode} - Duration: {duration.TotalMilliseconds}ms");
}
}
}
public class CORSMiddleware
{
private readonly RequestDelegate _next;
public CORSMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
if (context.Request.Method == "OPTIONS")
{
context.Response.StatusCode = 200;
return;
}
await _next(context);
}
}
// API响应格式
public class ApiResponse
{
public bool Success { get; set; }
public object Data { get; set; }
public string Message { get; set; }
public DateTime Timestamp { get; set; }
public int Code { get; set; }
public static ApiResponse NotFound(string message = "Resource not found")
{
return Error(message, 404);
}
public static ApiResponse BadRequest(string message = "Bad request")
{
return Error(message, 400);
}
public static ApiResponse Unauthorized(string message = "Unauthorized")
{
return Error(message, 401);
}
}
// 统一响应包装器
public class PagedResponse<T>
{
public IEnumerable<T> Items { get; set; }
public int TotalCount { get; set; }
public int PageNumber { get; set; }
public int PageSize { get; set; }
public int TotalPages { get; set; }
public bool HasNextPage { get; set; }
public bool HasPreviousPage { get; set; }
public static PagedResponse<T> Create(IEnumerable<T> items, int totalCount, int pageNumber, int pageSize)
{
return new PagedResponse<T>
{
Items = items,
TotalCount = totalCount,
PageNumber = pageNumber,
PageSize = pageSize,
TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize),
HasNextPage = pageNumber < (int)Math.Ceiling(totalCount / (double)pageSize),
HasPreviousPage = pageNumber > 1
};
}
}
// 分页参数
public class PaginationParams
{
public int PageNumber { get; set; } = 1;
public int PageSize { get; set; } = 10;
public string SortBy { get; set; }
public string SortOrder { get; set; } = "asc";
public string Search { get; set; }
}
// 排序参数
public class SortParams
{
public string Field { get; set; }
public string Direction { get; set; } = "asc";
}
}