using Gs.Toolbox.ApiCore.Abstract.Mvc; using Gs.Toolbox.ApiCore.Common.Helper; using Gs.Toolbox.ApiCore.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ActionConstraints; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Mvc.ModelBinding; namespace Gs.Toolbox.ApiCore.Common.Mvc; public class CustomApplicationModelConvention : IApplicationModelConvention { public void Apply(ApplicationModel application) { foreach (var controller in application.Controllers) if (controller.ControllerType.IsAssignableTo(typeof(IRomteService))) { ConfigureApiExplorer(controller); ConfigureSelector(controller); ConfigureParameters(controller); } } //直接抄abp代码 private void ConfigureParameters(ControllerModel controller) { foreach (var action in controller.Actions) foreach (var prm in action.Parameters) { if (prm.BindingInfo != null) continue; if (!TypeHelper.IsPrimitiveExtended(prm.ParameterInfo.ParameterType, includeEnums: true)) if (CanUseFormBodyBinding(action, prm)) prm.BindingInfo = BindingInfo.GetBindingInfo(new[] { new FromBodyAttribute() }); } } private bool CanUseFormBodyBinding(ActionModel action, ParameterModel parameter) { if (parameter.ParameterName == "id") return false; foreach (var selector in action.Selectors) { if (selector.ActionConstraints == null) continue; foreach (var actionConstraint in selector.ActionConstraints) { var httpMethodActionConstraint = actionConstraint as HttpMethodActionConstraint; if (httpMethodActionConstraint == null) continue; if (httpMethodActionConstraint.HttpMethods.All(hm => hm.IsIn("GET", "DELETE", "TRACE", "HEAD"))) return false; } } return true; } private void ConfigureSelector(ControllerModel controller) { //先不使用特性,做个最简单的 var controllerName = controller.ControllerName; //实际上路由凭借还是自己填补RouteAttribute特性 foreach (var action in controller.Actions) { action.Selectors.Clear(); var reqMethod = GetRequestMethod(action); if (!string.IsNullOrEmpty(reqMethod)) action.Selectors.Add(new SelectorModel { AttributeRouteModel = new AttributeRouteModel( new RouteAttribute( $"/{controllerName}/{action.ActionName}")), ActionConstraints = { new HttpMethodActionConstraint(new[] { reqMethod }) } }); } } private string GetRequestMethod(ActionModel action) { try { var reqM = action.Attributes.OfType() .ToList(); return reqM.Last()._method.ToString(); } catch (Exception ex) { return ""; } } private void ConfigureApiExplorer(ControllerModel controller) { //将自动发现的控制器显示出来 controller.ApiExplorer.IsVisible = true; foreach (var action in controller.Actions) ConfigureApiExplorer(action); } private void ConfigureApiExplorer(ActionModel action) { action.ApiExplorer.IsVisible = true; } }