有个项目需要获取项目内所有Action,并在凌晨定时任务跑完所有接口检查是否有接口报错,写了如下方法:
/// <summary> /// 获取Action注释 /// </summary> /// <param name="root"></param> /// <param name="method">方法</param> /// <param name="xmlPath">项目xml路径</param> /// <returns></returns> static string? GetMethodSummary(XmlElement root, MethodInfo method, string xmlPath) { // 查找方法的注释节点 string memberName = GetMethodSignature(method); XmlNode? memberNode = root.SelectSingleNode($"//member[@name='{memberName}']"); // 获取方法的 <summary> 注释 XmlNode? summaryNode = memberNode?.SelectSingleNode("summary"); string? summary = summaryNode?.InnerText.Trim(); return summary; }
/// <summary> /// 获取控制器注释 /// </summary> /// <param name="root"></param> /// <param name="controllerType">控制器</param> /// <param name="xmlPath">项目xlm路径</param> /// <returns></returns> static string? GetMemberSummary(XmlElement root, Type controllerType, string xmlPath) { // 查找方法的注释节点 string memberName = $"T:{controllerType.FullName}"; XmlNode? memberNode = root.SelectSingleNode($"//member[@name='{memberName}']"); // 获取方法的 <summary> 注释 XmlNode? summaryNode = memberNode?.SelectSingleNode("summary"); string? summary = summaryNode?.InnerText.Trim(); return summary; }
/// <summary> /// 获取方法签名 /// </summary> /// <param name="methodInfo"></param> /// <returns></returns> static string GetMethodSignature(MethodInfo methodInfo) { StringBuilder signatureBuilder = new StringBuilder(); signatureBuilder.Append($"M:{methodInfo.DeclaringType!.FullName}.{methodInfo.Name}"); ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length > 0) { signatureBuilder.Append("("); for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameter = parameters[i]; // 判断是否为泛型类型 if (parameter.ParameterType.IsGenericType) { Type genericTypeDefinition = parameter.ParameterType.GetGenericTypeDefinition(); Type[] genericArguments = parameter.ParameterType.GetGenericArguments(); string typeName = $"{genericTypeDefinition.FullName!.Remove(genericTypeDefinition.FullName.IndexOf('`'))}{{"; for (int j = 0; j < genericArguments.Length; j++) { typeName += $"{genericArguments[j].FullName},"; } typeName = typeName.TrimEnd(',') + "}"; signatureBuilder.Append(typeName); } else { signatureBuilder.Append(parameter.ParameterType.FullName); } if (i < parameters.Length - 1) { signatureBuilder.Append(","); } } signatureBuilder.Append(")"); } return signatureBuilder.ToString(); }
实体类:
ublic class Themeinterface { /// <summary> /// 方法 /// </summary> [Description("方法")] [StringLength(50)] [Column("Action")] public string Action { get; set; } /// <summary> /// 方法特性 /// </summary> [Description("方法特性")] [Column("ActionAttributes")] public string? ActionAttributes { get; set; } /// <summary> /// 方法名称 /// </summary> [Description("方法名称")] [Column("ActionName")] public string? ActionName { get; set; } /// <summary> /// 方法参数 /// </summary> [Description("方法参数")] [Column("ActionParams")] public string? ActionParams { get; set; } /// <summary> /// 控制器 /// </summary> [Description("控制器")] [StringLength(255)] [Column("Controller")] public string Controller { get; set; } /// <summary> /// 控制器名称 /// </summary> [Description("控制器名称")] [Column("ControllerName")] public string? ControllerName { get; set; } [Key] [Column("Id")] public int Id { get; set; } /// <summary> /// 调用时间 /// </summary> [Description("调用时间")] [Column("InvokeTime")] public int? InvokeTime { get; set; } /// <summary> /// 执行状态 /// </summary> public string Status { get; set; } /// <summary> /// /// </summary> public int StatusCode { get; set; } /// <summary> /// 请求方法 /// </summary> public string? Method { get; set; } /// <summary> /// /// </summary> public string? IP { get; set; } /// <summary> /// 异常 /// </summary> public string? Exception { get; set; } /// <summary> /// 请求路径 /// </summary> public string? Path { get; set; } /// <summary> /// 请求参数 /// </summary> public string? QueryString { get; set; } /// <summary> /// /// </summary> public DateTime? CreateTime { get; set; } /// <summary> /// /// </summary> public DateTime? UpdateTime { get; set; } }
使用:
/// <summary> /// 获取所有接口 /// </summary> /// <returns></returns> public static List<Themeinterface> GetAllInterface() { // 获取方法的 XML 文档路径 string xmlPath = Assembly.GetExecutingAssembly().Location.Replace("dll", "xml"); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlPath); XmlElement root = xmlDoc.DocumentElement!; var childControllers = Assembly.GetExecutingAssembly() .GetTypes() .Where(t => t.IsSubclassOf(typeof(BaseController)) && t != typeof(BaseController) && !t.IsDefined(typeof(IgnoreInterfaceAttribute))) .ToList(); List<Themeinterface> themeinterfaces = new(); foreach (var controllerType in childControllers) { var actions = controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => (typeof(IActionResult).IsAssignableFrom(m.ReturnType) || typeof(Task<IActionResult>).IsAssignableFrom(m.ReturnType)) && m.DeclaringType == controllerType && !m.IsDefined(typeof(IgnoreInterfaceAttribute))) .Select(m => new { ActionName = m.Name, Parameters = m.GetParameters() .Select(p => new { Name = p.Name, Type = p.ParameterType.FullName, Attributes = p.GetCustomAttributes().Select(attr => attr.GetType().Name).ToList() }) .ToList(), ActionSummary = GetMethodSummary(root, m, xmlPath), Method = m.GetCustomAttributes(typeof(HttpPostAttribute), false).Cast<HttpPostAttribute>().FirstOrDefault() == null ? "GET" : "POST" }) .ToList(); foreach (var action in actions) { Dictionary<string, object> actionAttributes = new(); foreach (var parameter in action.Parameters) { var key = $"{parameter.Type} {parameter.Name}"; if (parameter.Attributes.Any()) { actionAttributes.Add(key, string.Join(", ", parameter.Attributes)); } } themeinterfaces.Add(new Themeinterface { Action = action.ActionName, ActionName = action.ActionSummary, ActionAttributes = JsonConvert.SerializeObject(actionAttributes.Select(p => p.Value)), //ActionParams = string.Join(", ", action.Parameters.Select(p => p.Name)), Controller = controllerType.FullName!, ControllerName = GetMemberSummary(root, controllerType, xmlPath), Method = action.Method }); } } return themeinterfaces; }
标签:core,set,string,get,signatureBuilder,Api,Action,parameter,public From: https://www.cnblogs.com/runningprogrammer/p/controller-action-summary.html