minimal api 模型验证+ 方法级别的过滤器暂时未有解决方案
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-10-16 09:03:12 +08:00
parent 74a0c8923c
commit 8be3cc9e78
7 changed files with 104 additions and 34 deletions
@@ -8,13 +8,9 @@ namespace IRaCIS.Core.Application.Filter;
public class ModelActionFilter : ActionFilterAttribute, IActionFilter
public class ModelActionFilter(IStringLocalizer _localizer) : ActionFilterAttribute, IActionFilter
{
public IStringLocalizer _localizer;
public ModelActionFilter(IStringLocalizer localizer)
{
_localizer = localizer;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
@@ -1,26 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace IRaCIS.Core.Application.Filter;
#region snippet_DisableFormValueModelBindingAttribute
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var factories = context.ValueProviderFactories;
//factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
context.HttpContext.Request.EnableBuffering();
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
#endregion
@@ -0,0 +1,58 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.BusinessFilter;
public class ModelValidationEndpointFilter(IStringLocalizer _localizer) : IEndpointFilter
{
public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
{
var httpContext = context.HttpContext;
//// 1. 获取路由参数并验证
//foreach (var routeValue in httpContext.Request.RouteValues)
//{
// {
// return Results.BadRequest(new { ErrorMessage = $"Invalid format for {routeValue.Key}." });
// }
//}
//// 2. 获取查询参数并验证
//foreach (var queryValue in httpContext.Request.Query)
//{
// {
// return Results.BadRequest(new { ErrorMessage = $"Invalid format for {queryValue.Key}." });
// }
//}
// 获取请求中的模型参数
var model = context.Arguments.FirstOrDefault(a => a != null && a.GetType().IsClass);
// 仅当模型存在时执行验证
if (model != null)
{
var validationResults = new List<ValidationResult>();
var validationContext = new ValidationContext(model);
bool isValid = Validator.TryValidateObject(model, validationContext, validationResults, true);
if (!isValid)
{
var validationErrors = validationResults.Select(vr => vr.ErrorMessage).ToArray();
return Results.Json(new
{
ErrorMessage = _localizer["ModelAction_InvalidAPIParameter"],
Errors = validationErrors
}, statusCode: StatusCodes.Status400BadRequest);
}
}
// 验证通过,继续执行
return await next(context);
}
}
@@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.BusinessFilter;
public class TrialGlobalLimitEndpointFilter : IEndpointFilter
{
public ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
{
throw new NotImplementedException();
}
}
+2 -1
View File
@@ -56,7 +56,8 @@ namespace IRaCIS.Core.Application.Service
return Task.FromResult(list);
}
public IResponseOutput GetTest()
[AllowAnonymous]
public IResponseOutput GetTest(Guid trialId,int num, TestModel testModel)
{
//throw new BusinessValidationFailedException("手动抛出的异常");