using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Linq;
using Microsoft.AspNetCore.Http;
using SqlSugar;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Text.Json;
using System.Collections.Generic;
using System.Data;
using Microsoft.Extensions.Hosting;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using SqlSugar.IOC;
using Microsoft.AspNetCore.Authorization;
using VideoAnalysisCore.Common.Dto;
using VideoAnalysisCore.Common;
using VideoAnalysisCore.Model;
namespace Learn.VideoAnalysis.API.Expand
{
///
/// 使用该属性,接口对结果原样输出,不做包装
///
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = false)]
public class ResultIgnore : Attribute { }
///
/// http接口日志启用
///
public class HttpLogEnable : Attribute { }
///
/// Http请求过滤器
///
public class HttpLogAttribute : ActionFilterAttribute, IAsyncExceptionFilter
{
readonly Stopwatch _stopwatch;//统计程序耗时
public HttpLogAttribute()
{
_stopwatch = Stopwatch.StartNew();
}
///
/// 执行接口前文件做缓存处理
///
///
///
public void ExecutingCached(ActionExecutingContext context)
{
//特殊处理:ResultIgnore,不进行返回结果包装,原样输出
var endpoint = context.HttpContext.GetEndpoint();
var request = context.HttpContext.Request;
// 1. 只有非 GET 请求且不是文件上传时才读取 Body
if (!request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase)
&& !request.HasFormContentType)
{
// 确保从头开始读
request.Body.Position = 0;
// 使用 leaveOpen: true 防止 StreamReader 关闭底层的 Request.Body
using (var reader = new System.IO.StreamReader(request.Body, System.Text.Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: 1024, leaveOpen: true))
{
var body = reader.ReadToEnd();
context.HttpContext.Items["RequestBodyRaw"] = body;
request.Body.Position = 0;
}
}
// 直接返回原始结果,不封装
if (endpoint?.Metadata.GetMetadata() == null) return;
if (context.HttpContext.Request.HasFormContentType &&
context.HttpContext.Request.Form.Files != null &&
context.HttpContext.Request.Form.Files.Count() > 0)
{
context.HttpContext.Items["FileCached"]=
context.HttpContext.Request.Form.Files.Select(s =>
{
var stream = new MemoryStream();
s.CopyTo(stream);
stream.Position = 0;
return (s, stream);
}).ToArray();
}
}
///
/// 执行接口前400 处理
///
///
///
public void Executing400(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
var errMsg = string.Join(',', context.ModelState.Values.SelectMany(s => s.Errors.Select(e => e.ErrorMessage)));
Oh.ModelError(errMsg);
}
}
private bool HasAttribute(ActionExecutedContext context) where T : Attribute
{
if (context.ActionDescriptor is ControllerActionDescriptor descriptor)
{
// 检查方法上是否有 SkipApiResultAttribute
if (descriptor.MethodInfo.GetCustomAttributes(typeof(T), false).Any())
return true;
// 检查控制器上是否有 SkipApiResultAttribute
if (descriptor.ControllerTypeInfo.GetCustomAttributes(typeof(T), false).Any())
return true;
}
return false;
}
///
/// 接口结果格式化
///
///
public BaseReturn