From 8be3cc9e78d7ed651b7d588fcbe7370f8bd98556 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 16 Oct 2024 09:03:12 +0800 Subject: [PATCH] =?UTF-8?q?minimal=20api=20=E6=A8=A1=E5=9E=8B=E9=AA=8C?= =?UTF-8?q?=E8=AF=81+=20=E6=96=B9=E6=B3=95=E7=BA=A7=E5=88=AB=E7=9A=84?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E5=99=A8=E6=9A=82=E6=97=B6=E6=9C=AA=E6=9C=89?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/UploadDownLoadController.cs | 24 ++++++++ IRaCIS.Core.API/Progranm.cs | 2 +- .../LegacyController/ModelActionFilter .cs | 8 +-- .../LegacyController/ModelBinding.cs | 26 --------- .../ModelValidationEndpointFilter.cs | 58 +++++++++++++++++++ .../TrialGlobalLimitEndpointFilter.cs | 17 ++++++ IRaCIS.Core.Application/TestService.cs | 3 +- 7 files changed, 104 insertions(+), 34 deletions(-) delete mode 100644 IRaCIS.Core.Application/BusinessFilter/LegacyController/ModelBinding.cs create mode 100644 IRaCIS.Core.Application/BusinessFilter/MinimalAPI/ModelValidationEndpointFilter.cs create mode 100644 IRaCIS.Core.Application/BusinessFilter/MinimalAPI/TrialGlobalLimitEndpointFilter.cs diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index 847a069bb..c011f1f40 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -18,6 +18,8 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.StaticFiles; using Microsoft.AspNetCore.WebUtilities; @@ -43,6 +45,28 @@ namespace IRaCIS.Core.API.Controllers #region 上传基类封装 + + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] + public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter + { + public void OnResourceExecuting(ResourceExecutingContext context) + { + + + var factories = context.ValueProviderFactories; + //factories.RemoveType(); + factories.RemoveType(); + factories.RemoveType(); + context.HttpContext.Request.EnableBuffering(); + } + + public void OnResourceExecuted(ResourceExecutedContext context) + { + } + } + + [DisableFormValueModelBinding] public abstract class UploadBaseController : ControllerBase { diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 8aad500c0..48e5a45dd 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -91,7 +91,6 @@ builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resourc // 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim() builder.Services.AddControllers(options => { - //options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); @@ -150,6 +149,7 @@ builder.Services.AddMasaMinimalAPIs(options => options.RouteHandlerBuilder= t=> { t.RequireAuthorization() .AddEndpointFilter() + .AddEndpointFilter() .AddEndpointFilter() .WithGroupName("Institution"); }; diff --git a/IRaCIS.Core.Application/BusinessFilter/LegacyController/ModelActionFilter .cs b/IRaCIS.Core.Application/BusinessFilter/LegacyController/ModelActionFilter .cs index a52ca0a52..63255f4fa 100644 --- a/IRaCIS.Core.Application/BusinessFilter/LegacyController/ModelActionFilter .cs +++ b/IRaCIS.Core.Application/BusinessFilter/LegacyController/ModelActionFilter .cs @@ -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) { diff --git a/IRaCIS.Core.Application/BusinessFilter/LegacyController/ModelBinding.cs b/IRaCIS.Core.Application/BusinessFilter/LegacyController/ModelBinding.cs deleted file mode 100644 index 994d9fa09..000000000 --- a/IRaCIS.Core.Application/BusinessFilter/LegacyController/ModelBinding.cs +++ /dev/null @@ -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(); - factories.RemoveType(); - factories.RemoveType(); - context.HttpContext.Request.EnableBuffering(); - } - - public void OnResourceExecuted(ResourceExecutedContext context) - { - } -} -#endregion diff --git a/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/ModelValidationEndpointFilter.cs b/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/ModelValidationEndpointFilter.cs new file mode 100644 index 000000000..32af30c35 --- /dev/null +++ b/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/ModelValidationEndpointFilter.cs @@ -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 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(); + 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); + } +} diff --git a/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/TrialGlobalLimitEndpointFilter.cs b/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/TrialGlobalLimitEndpointFilter.cs new file mode 100644 index 000000000..d50a6c102 --- /dev/null +++ b/IRaCIS.Core.Application/BusinessFilter/MinimalAPI/TrialGlobalLimitEndpointFilter.cs @@ -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 InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) + { + throw new NotImplementedException(); + } +} diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index b33c86a67..419a86ebb 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -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("手动抛出的异常");