/// <summary> /// 配置控制器 /// </summary> /// <param name="controller">控制器模型</param> /// <param name="controllerApiDescriptionSettings">接口描述配置</param> private void ConfigureController(ControllerModel controller, ApiDescriptionSettingsAttribute controllerApiDescriptionSettings) { // 配置控制器名称 ConfigureControllerName(controller, controllerApiDescriptionSettings); // 存储排序给 Swagger 使用 Penetrates.ControllerOrderCollection.TryAdd(controller.ControllerName, controllerApiDescriptionSettings?.Order ?? 0); var actions = controller.Actions; // 查找所有重复的方法签名 var repeats = actions.GroupBy(u => new { u.ActionMethod.ReflectedType.Name, Signature = u.ActionMethod.ToString() }) .Where(u => u.Count() > 1) .SelectMany(u => u.Where(u => u.ActionMethod.ReflectedType.Name != u.ActionMethod.DeclaringType.Name)); // 2021年04月01日 https://docs.microsoft.com/en-US/aspnet/core/web-api/?view=aspnetcore-5.0#binding-source-parameter-inference // 判断是否贴有 [ApiController] 特性 var hasApiControllerAttribute = controller.Attributes.Any(u => u.GetType() == typeof(ApiControllerAttribute)); foreach (var action in actions) { // 跳过相同方法签名 if (repeats.Contains(action)) { action.ApiExplorer.IsVisible = false; continue; } ; var actionMethod = action.ActionMethod; var actionApiDescriptionSettings = actionMethod.IsDefined(typeof(ApiDescriptionSettingsAttribute), true) ? actionMethod.GetCustomAttribute <ApiDescriptionSettingsAttribute>(true) : default; ConfigureAction(action, actionApiDescriptionSettings, controllerApiDescriptionSettings, hasApiControllerAttribute); } }
/// <summary> /// 配置控制器 /// </summary> /// <param name="controller">控制器模型</param> /// <param name="apiDescriptionSettings">接口描述配置</param> private void ConfigureController(ControllerModel controller, ApiDescriptionSettingsAttribute apiDescriptionSettings) { // 配置控制器名称 ConfigureControllerName(controller, apiDescriptionSettings); // 存储排序给 Swagger 使用 Penetrates.ControllerOrderCollection.TryAdd(controller.ControllerName, apiDescriptionSettings?.Order ?? 0); var actions = controller.Actions; // 查找所有重复的方法签名 var repeats = actions.GroupBy(u => new { u.ActionMethod.ReflectedType.Name, Signature = u.ActionMethod.ToString() }) .Where(u => u.Count() > 1) .SelectMany(u => u.Where(u => u.ActionMethod.ReflectedType.Name != u.ActionMethod.DeclaringType.Name)); foreach (var action in actions) { // 跳过相同方法签名 if (repeats.Contains(action)) { action.ApiExplorer.IsVisible = false; continue; } ; var actionApiDescriptionSettings = action.Attributes.FirstOrDefault(u => u is ApiDescriptionSettingsAttribute) as ApiDescriptionSettingsAttribute; ConfigureAction(action, actionApiDescriptionSettings, apiDescriptionSettings); } }
/// <summary> /// 配置控制器 /// </summary> /// <param name="controller">控制器模型</param> /// <param name="apiDescriptionSettings">接口描述配置</param> private void ConfigureController(ControllerModel controller, ApiDescriptionSettingsAttribute apiDescriptionSettings) { // 配置控制器名称 ConfigureControllerName(controller, apiDescriptionSettings); var actions = controller.Actions; foreach (var action in actions) { var actionApiDescriptionSettings = action.Attributes.FirstOrDefault(u => u is ApiDescriptionSettingsAttribute) as ApiDescriptionSettingsAttribute; ConfigureAction(action, actionApiDescriptionSettings, apiDescriptionSettings); } }
/// <summary> /// 配置动作方法名称 /// </summary> /// <param name="action">动作方法模型</param> /// <param name="apiDescriptionSettings">接口描述配置</param> /// <param name="controllerApiDescriptionSettings"></param> private void ConfigureActionName(ActionModel action, ApiDescriptionSettingsAttribute apiDescriptionSettings, ApiDescriptionSettingsAttribute controllerApiDescriptionSettings) { action.ActionName = ConfigureControllerAndActionName(apiDescriptionSettings, action.ActionName, _dynamicApiControllerSettings.AbandonActionAffixes, (tempName) => { // 处理动作方法名称谓词 if (!CheckIsKeepVerb(apiDescriptionSettings, controllerApiDescriptionSettings)) { var words = Penetrates.SplitCamelCase(tempName); var verbKey = words.First().ToLower(); // 处理类似 getlist,getall 多个单词 if (words.Length > 1 && Penetrates.VerbToHttpMethods.ContainsKey((words[0] + words[1]).ToLower())) { tempName = tempName[(words[0] + words[1]).Length..]; }
/// <summary> /// 配置动作方法 /// </summary> /// <param name="action">控制器模型</param> /// <param name="apiDescriptionSettings">接口描述配置</param> /// <param name="controllerApiDescriptionSettings">控制器接口描述配置</param> private void ConfigureAction(ActionModel action, ApiDescriptionSettingsAttribute apiDescriptionSettings, ApiDescriptionSettingsAttribute controllerApiDescriptionSettings) { // 配置动作方法接口可见性 ConfigureActionApiExplorer(action); // 配置动作方法名称 ConfigureActionName(action, apiDescriptionSettings, controllerApiDescriptionSettings); // 配置动作方法请求谓词特性 ConfigureActionHttpMethodAttribute(action); // 配置引用类型参数 ConfigureClassTypeParameter(action); // 配置动作方法路由特性 ConfigureActionRouteAttribute(action, apiDescriptionSettings, controllerApiDescriptionSettings); }
/// <summary> /// 配置控制器区域 /// </summary> /// <param name="controller"></param> /// <param name="controllerApiDescriptionSettings"></param> private void ConfigureControllerArea(ControllerModel controller, ApiDescriptionSettingsAttribute controllerApiDescriptionSettings) { // 如果配置了区域,则跳过 if (controller.RouteValues.ContainsKey("area")) { return; } // 如果没有配置区域,则跳过 var area = controllerApiDescriptionSettings?.Area ?? _dynamicApiControllerSettings.DefaultArea; if (string.IsNullOrWhiteSpace(area)) { return; } controller.RouteValues["area"] = area; }
/// <summary> /// 配置动作方法 /// </summary> /// <param name="action">控制器模型</param> /// <param name="apiDescriptionSettings">接口描述配置</param> /// <param name="controllerApiDescriptionSettings">控制器接口描述配置</param> private void ConfigureAction(ActionModel action, ApiDescriptionSettingsAttribute apiDescriptionSettings, ApiDescriptionSettingsAttribute controllerApiDescriptionSettings) { // 配置动作方法接口可见性 ConfigureActionApiExplorer(action); // 配置动作方法名称 ConfigureActionName(action, apiDescriptionSettings, controllerApiDescriptionSettings); // 配置动作方法请求谓词特性 ConfigureActionHttpMethodAttribute(action); // 配置引用类型参数 ConfigureClassTypeParameter(action); // 配置动作方法路由特性 ConfigureActionRouteAttribute(action, apiDescriptionSettings, controllerApiDescriptionSettings); // 配置动作方法规范化特性 if (UnifyContext.IsEnabledUnifyHandle) { ConfigureActionUnifyResultAttribute(action); } }
/// <summary> /// 配置动作方法 /// </summary> /// <param name="action">控制器模型</param> /// <param name="apiDescriptionSettings">接口描述配置</param> /// <param name="controllerApiDescriptionSettings">控制器接口描述配置</param> /// <param name="hasApiControllerAttribute">是否贴有 ApiController 特性</param> private void ConfigureAction(ActionModel action, ApiDescriptionSettingsAttribute apiDescriptionSettings, ApiDescriptionSettingsAttribute controllerApiDescriptionSettings, bool hasApiControllerAttribute) { // 配置动作方法接口可见性 ConfigureActionApiExplorer(action); // 配置动作方法名称 var(isLowercaseRoute, isKeepName) = ConfigureActionName(action, apiDescriptionSettings, controllerApiDescriptionSettings); // 配置动作方法请求谓词特性 ConfigureActionHttpMethodAttribute(action); // 配置引用类型参数 ConfigureClassTypeParameter(action); // 配置动作方法路由特性 ConfigureActionRouteAttribute(action, apiDescriptionSettings, controllerApiDescriptionSettings, isLowercaseRoute, isKeepName, hasApiControllerAttribute); // 配置动作方法规范化特性 if (UnifyContext.EnabledUnifyHandler) { ConfigureActionUnifyResultAttribute(action); } }
/// <summary> /// 配置控制器 /// </summary> /// <param name="controller">控制器模型</param> /// <param name="apiDescriptionSettings">接口描述配置</param> private void ConfigureController(ControllerModel controller, ApiDescriptionSettingsAttribute apiDescriptionSettings) { // 配置控制器名称 ConfigureControllerName(controller, apiDescriptionSettings); var actions = controller.Actions; // 查找所有重复的方法签命 var repeats = actions.GroupBy(u => new { u.ActionMethod.ReflectedType.Name, Signature = u.ActionMethod.ToString() }) .Where(u => u.Count() > 1) .SelectMany(u => u.Where(u => u.ActionMethod.ReflectedType.Name != u.ActionMethod.DeclaringType.Name)); foreach (var action in actions) { // 跳过相同方法签命 if (repeats.Contains(action)) { continue; } var actionApiDescriptionSettings = action.Attributes.FirstOrDefault(u => u is ApiDescriptionSettingsAttribute) as ApiDescriptionSettingsAttribute; ConfigureAction(action, actionApiDescriptionSettings, apiDescriptionSettings); } }
/// <summary> /// 配置控制器名称 /// </summary> /// <param name="controller">控制器模型</param> /// <param name="apiDescriptionSettings">接口描述配置</param> private void ConfigureControllerName(ControllerModel controller, ApiDescriptionSettingsAttribute apiDescriptionSettings) { controller.ControllerName = ConfigureControllerAndActionName(apiDescriptionSettings, controller.ControllerType.Name, _dynamicApiControllerSettings.AbandonControllerAffixes, _ => _); }