From d73ab4d10d20668d827f00b82a04429265892c14 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 16 Jan 2026 06:53:44 +0000 Subject: [PATCH 01/22] Initial plan From bb45fb627248359036d0a18fd68d04677e375b3b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 16 Jan 2026 07:00:09 +0000 Subject: [PATCH 02/22] Add reflection-based attribute retrieval for Circles component Co-authored-by: ArgoZhang <22001478+ArgoZhang@users.noreply.github.com> --- .../Components/Samples/Circles.razor.cs | 60 +----- .../Data/AttributeItem.cs | 6 + .../ComponentAttributeCacheService.cs | 181 ++++++++++++++++++ src/BootstrapBlazor/BootstrapBlazor.csproj | 1 + 4 files changed, 196 insertions(+), 52 deletions(-) create mode 100644 src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs diff --git a/src/BootstrapBlazor.Server/Components/Samples/Circles.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Circles.razor.cs index 897ed8eff9e..cd3da7da243 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Circles.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Circles.razor.cs @@ -3,6 +3,8 @@ // See the LICENSE file in the project root for more information. // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone +using BootstrapBlazor.Server.Services; + namespace BootstrapBlazor.Server.Components.Samples; /// @@ -19,59 +21,13 @@ private void Add(int interval) } /// - /// GetAttributes + /// GetAttributes - 使用反射和缓存自动获取 Circle 组件属性 /// /// - private AttributeItem[] GetAttributes() => - [ - new() - { - Name = "Width", - Description = Localizer["Width"], - Type = "int", - ValueList = "", - DefaultValue = "120" - }, - new() - { - Name = "StrokeWidth", - Description = Localizer["StrokeWidth"], - Type = "int", - ValueList = "", - DefaultValue = "2" - }, - new() - { - Name = "Value", - Description = Localizer["Value"], - Type = "int", - ValueList = "0-100", - DefaultValue = "0" - }, - new() - { - Name = "Color", - Description = Localizer["Color"], - Type = "Color", - ValueList = "Primary / Secondary / Success / Danger / Warning / Info / Dark", - DefaultValue = "Primary" - }, - new() - { - Name = "ShowProgress", - Description = Localizer["ShowProgress"], - Type = "bool", - ValueList = "true / false", - DefaultValue = "true" - }, - new() - { - Name = "ChildContent", - Description = Localizer["ChildContent"], - Type = "RenderFragment", - ValueList = "", - DefaultValue = "" - } - ]; + private AttributeItem[] GetAttributes() + { + // 通过示例组件名称 Circles 确定组件类型为 Circle + return ComponentAttributeCacheService.GetAttributes(typeof(BootstrapBlazor.Components.Circle)); + } } diff --git a/src/BootstrapBlazor.Server/Data/AttributeItem.cs b/src/BootstrapBlazor.Server/Data/AttributeItem.cs index fe24314716a..2a9439617d9 100644 --- a/src/BootstrapBlazor.Server/Data/AttributeItem.cs +++ b/src/BootstrapBlazor.Server/Data/AttributeItem.cs @@ -41,4 +41,10 @@ public class AttributeItem /// [DisplayName("默认值")] public string DefaultValue { get; set; } = ""; + + /// + /// 获得/设置 版本 + /// + [DisplayName("版本")] + public string Version { get; set; } = ""; } diff --git a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs new file mode 100644 index 00000000000..a873cc937ca --- /dev/null +++ b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs @@ -0,0 +1,181 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License +// See the LICENSE file in the project root for more information. +// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone + +using System.Collections.Concurrent; +using System.ComponentModel; +using System.Reflection; +using System.Xml.Linq; +using BootstrapBlazor.Server.Data; +using Microsoft.AspNetCore.Components; + +namespace BootstrapBlazor.Server.Services; + +/// +/// 组件属性缓存服务 +/// +public static class ComponentAttributeCacheService +{ + private static readonly ConcurrentDictionary _cache = new(); + + /// + /// 获取组件的 AttributeItem 列表(带缓存) + /// + public static AttributeItem[] GetAttributes(Type componentType) + { + return _cache.GetOrAdd(componentType, type => + { + var attributes = new List(); + var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance) + .Where(p => p.GetCustomAttribute() != null); + + foreach (var property in properties) + { + var item = new AttributeItem + { + Name = property.Name, + Type = GetFriendlyTypeName(property.PropertyType), + Description = GetSummary(property) ?? "", + DefaultValue = GetDefaultValue(property) ?? "", + ValueList = GetValueList(property) ?? "", + Version = GetVersion(property) ?? "" + }; + attributes.Add(item); + } + + return attributes.ToArray(); + }); + } + + /// + /// 从 XML 注释获取 summary + /// + private static string? GetSummary(PropertyInfo property) + { + var xmlDoc = GetXmlDocumentation(property.DeclaringType?.Assembly); + if (xmlDoc == null) return null; + + var memberName = $"P:{property.DeclaringType?.FullName}.{property.Name}"; + var element = xmlDoc.Descendants("member") + .FirstOrDefault(x => x.Attribute("name")?.Value == memberName); + + return element?.Element("summary")?.Value.Trim(); + } + + /// + /// 从 XML 注释的 para version 节点获取版本信息 + /// + private static string? GetVersion(PropertyInfo property) + { + var xmlDoc = GetXmlDocumentation(property.DeclaringType?.Assembly); + if (xmlDoc == null) return null; + + var memberName = $"P:{property.DeclaringType?.FullName}.{property.Name}"; + var element = xmlDoc.Descendants("member") + .FirstOrDefault(x => x.Attribute("name")?.Value == memberName); + + // 查找 10.0.0 + var versionElement = element?.Descendants("para") + .SelectMany(p => p.Elements("version")) + .FirstOrDefault(); + + return versionElement?.Value.Trim(); + } + + /// + /// 获取默认值 + /// + private static string? GetDefaultValue(PropertyInfo property) + { + var defaultValueAttr = property.GetCustomAttribute(); + if (defaultValueAttr != null) + { + return defaultValueAttr.Value?.ToString() ?? ""; + } + + // 从 XML 注释中提取 DefaultValue + var xmlDoc = GetXmlDocumentation(property.DeclaringType?.Assembly); + if (xmlDoc == null) return null; + + var memberName = $"P:{property.DeclaringType?.FullName}.{property.Name}"; + var element = xmlDoc.Descendants("member") + .FirstOrDefault(x => x.Attribute("name")?.Value == memberName); + + var defaultElement = element?.Element("value"); + return defaultElement?.Value.Trim(); + } + + /// + /// 获取可选值列表 + /// + private static string? GetValueList(PropertyInfo property) + { + // 如果是枚举类型,返回枚举值 + if (property.PropertyType.IsEnum) + { + return string.Join(" / ", Enum.GetNames(property.PropertyType)); + } + + return ""; + } + + /// + /// 获取友好的类型名称 + /// + private static string GetFriendlyTypeName(Type type) + { + if (type.IsGenericType) + { + var genericTypeName = type.GetGenericTypeDefinition().Name; + genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`')); + var genericArgs = string.Join(", ", type.GetGenericArguments().Select(GetFriendlyTypeName)); + return $"{genericTypeName}<{genericArgs}>"; + } + + return type.Name switch + { + "Int32" => "int", + "String" => "string", + "Boolean" => "bool", + "Double" => "double", + "Decimal" => "decimal", + _ => type.Name + }; + } + + /// + /// 获取 XML 文档 + /// + private static XDocument? GetXmlDocumentation(Assembly? assembly) + { + if (assembly == null) return null; + + try + { + var xmlPath = Path.Combine( + Path.GetDirectoryName(assembly.Location) ?? "", + Path.GetFileNameWithoutExtension(assembly.Location) + ".xml" + ); + + if (File.Exists(xmlPath)) + { + return XDocument.Load(xmlPath); + } + } + catch + { + // Ignore errors + } + + return null; + } + + /// + /// 清除缓存 + /// + public static void ClearCache() + { + _cache.Clear(); + } +} diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index edf9075973b..82bd97d9788 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -2,6 +2,7 @@ 10.2.2-beta02 + true From e9bf41193f459de0597d628450d0e9ee18a44d25 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 16 Jan 2026 07:04:06 +0000 Subject: [PATCH 03/22] Fix security issues in ComponentAttributeCacheService Co-authored-by: ArgoZhang <22001478+ArgoZhang@users.noreply.github.com> --- .../ComponentAttributeCacheService.cs | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs index a873cc937ca..a55c2be12b4 100644 --- a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs +++ b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs @@ -6,6 +6,7 @@ using System.Collections.Concurrent; using System.ComponentModel; using System.Reflection; +using System.Xml; using System.Xml.Linq; using BootstrapBlazor.Server.Data; using Microsoft.AspNetCore.Components; @@ -117,7 +118,7 @@ public static AttributeItem[] GetAttributes(Type componentType) return string.Join(" / ", Enum.GetNames(property.PropertyType)); } - return ""; + return null; } /// @@ -153,19 +154,41 @@ private static string GetFriendlyTypeName(Type type) try { + var assemblyLocation = assembly.Location; + if (string.IsNullOrEmpty(assemblyLocation)) + { + return null; + } + var xmlPath = Path.Combine( - Path.GetDirectoryName(assembly.Location) ?? "", - Path.GetFileNameWithoutExtension(assembly.Location) + ".xml" + Path.GetDirectoryName(assemblyLocation) ?? "", + Path.GetFileNameWithoutExtension(assemblyLocation) + ".xml" ); if (File.Exists(xmlPath)) { - return XDocument.Load(xmlPath); + // 使用安全的 XML 读取设置防止 XXE 攻击 + var settings = new XmlReaderSettings + { + DtdProcessing = DtdProcessing.Prohibit, + XmlResolver = null + }; + + using var reader = XmlReader.Create(xmlPath, settings); + return XDocument.Load(reader); } } - catch + catch (FileNotFoundException) + { + // XML 文档文件不存在,忽略 + } + catch (XmlException) + { + // XML 文档格式错误,忽略 + } + catch (UnauthorizedAccessException) { - // Ignore errors + // 没有访问权限,忽略 } return null; From e635568639e7db9aabe1cccd31f8a77c6c4df1d5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 16 Jan 2026 07:06:03 +0000 Subject: [PATCH 04/22] Fix IndexOf edge case in GetFriendlyTypeName Co-authored-by: ArgoZhang <22001478+ArgoZhang@users.noreply.github.com> --- .../Services/ComponentAttributeCacheService.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs index a55c2be12b4..667d2e0116a 100644 --- a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs +++ b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs @@ -129,7 +129,11 @@ private static string GetFriendlyTypeName(Type type) if (type.IsGenericType) { var genericTypeName = type.GetGenericTypeDefinition().Name; - genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`')); + var backtickIndex = genericTypeName.IndexOf('`'); + if (backtickIndex > 0) + { + genericTypeName = genericTypeName.Substring(0, backtickIndex); + } var genericArgs = string.Join(", ", type.GetGenericArguments().Select(GetFriendlyTypeName)); return $"{genericTypeName}<{genericArgs}>"; } From 4769d78f6363cd6751ac03055668b6915dddbf7a Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 16:16:19 +0800 Subject: [PATCH 05/22] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Components/AttributeTable.razor | 3 ++- .../Components/Components/AttributeTable.razor.cs | 13 ++++++++++++- .../Components/Samples/Circles.razor | 2 +- .../Services/ComponentAttributeCacheService.cs | 4 +--- .../Components/Circle/Circle.razor.cs | 3 ++- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor index 48f3aabc969..f7a92a984fe 100644 --- a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor +++ b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor @@ -1,4 +1,4 @@ -
+

@Title

@@ -8,6 +8,7 @@ +
diff --git a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs index 9d5f1ab4b8c..943ececb22b 100644 --- a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License // See the LICENSE file in the project root for more information. // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone @@ -26,6 +26,12 @@ public sealed partial class AttributeTable ///
[Parameter] public IEnumerable? Items { get; set; } + /// + /// + /// + [Parameter] + public Type? Type { get; set; } + /// /// OnInitialized 方法 /// @@ -34,5 +40,10 @@ protected override void OnInitialized() base.OnInitialized(); Title ??= Localizer[nameof(Title)]; + + if (Items == null && Type != null) + { + Items = ComponentAttributeCacheService.GetAttributes(Type); + } } } diff --git a/src/BootstrapBlazor.Server/Components/Samples/Circles.razor b/src/BootstrapBlazor.Server/Components/Samples/Circles.razor index cf5740f3201..a2bf2b61ad8 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Circles.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Circles.razor @@ -53,4 +53,4 @@ - + diff --git a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs index 667d2e0116a..65dbe9d9e01 100644 --- a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs +++ b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs @@ -8,8 +8,6 @@ using System.Reflection; using System.Xml; using System.Xml.Linq; -using BootstrapBlazor.Server.Data; -using Microsoft.AspNetCore.Components; namespace BootstrapBlazor.Server.Services; @@ -115,7 +113,7 @@ public static AttributeItem[] GetAttributes(Type componentType) // 如果是枚举类型,返回枚举值 if (property.PropertyType.IsEnum) { - return string.Join(" / ", Enum.GetNames(property.PropertyType)); + return string.Join("/", Enum.GetNames(property.PropertyType)); } return null; diff --git a/src/BootstrapBlazor/Components/Circle/Circle.razor.cs b/src/BootstrapBlazor/Components/Circle/Circle.razor.cs index 5aaf1bb57cf..c857b920c91 100644 --- a/src/BootstrapBlazor/Components/Circle/Circle.razor.cs +++ b/src/BootstrapBlazor/Components/Circle/Circle.razor.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License // See the LICENSE file in the project root for more information. // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone @@ -12,6 +12,7 @@ public sealed partial class Circle { /// /// 获得/设置 当前值 + /// 10.0.0 /// [Parameter] public int Value { get; set; } From a6564d76dc1e4a3d510e4aec0bde02fa46b4158d Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 16:18:43 +0800 Subject: [PATCH 06/22] =?UTF-8?q?doc:=20=E9=87=8D=E6=9E=84=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Samples/Circles.razor | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/Circles.razor b/src/BootstrapBlazor.Server/Components/Samples/Circles.razor index a2bf2b61ad8..89f2fa54a1a 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Circles.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Circles.razor @@ -12,15 +12,17 @@ -
- - +
+
+ + +
From 37e36a587524c2978b6d623bee44d9749bb114dc Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 20:10:43 +0800 Subject: [PATCH 07/22] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/BootstrapBlazor.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 82bd97d9788..edf9075973b 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -2,7 +2,6 @@ 10.2.2-beta02 - true From 0ac2cade63c2276d30e06f9a8a7bb046c7942c8e Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 20:10:59 +0800 Subject: [PATCH 08/22] =?UTF-8?q?chore:=20=E5=A2=9E=E5=8A=A0=20xml=20?= =?UTF-8?q?=E6=8B=B7=E8=B4=9D=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Directory.Build.targets | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/BootstrapBlazor.Server/Directory.Build.targets b/src/BootstrapBlazor.Server/Directory.Build.targets index 7e382f03fe4..db085097ba0 100644 --- a/src/BootstrapBlazor.Server/Directory.Build.targets +++ b/src/BootstrapBlazor.Server/Directory.Build.targets @@ -6,4 +6,12 @@ + + + + + + + + From 466daa95ed85d13d01a9ea42196aac86c93cd435 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 21:37:34 +0800 Subject: [PATCH 09/22] =?UTF-8?q?chore:=20=E8=B0=83=E6=95=B4=20Target=20?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Directory.Build.targets | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/BootstrapBlazor.Server/Directory.Build.targets b/src/BootstrapBlazor.Server/Directory.Build.targets index db085097ba0..c3c44e60247 100644 --- a/src/BootstrapBlazor.Server/Directory.Build.targets +++ b/src/BootstrapBlazor.Server/Directory.Build.targets @@ -1,17 +1,17 @@ - - - - - - - + - - + + + + + + + + From f16b4551fae2a92ee10a8f53e9f4ffe3003ed499 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 21:46:42 +0800 Subject: [PATCH 10/22] =?UTF-8?q?chore:=20=E5=A2=9E=E5=8A=A0=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/BaseComponents/BootstrapComponentBase.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/BootstrapBlazor/Components/BaseComponents/BootstrapComponentBase.cs b/src/BootstrapBlazor/Components/BaseComponents/BootstrapComponentBase.cs index 22fdcee4abf..87a2255f2d9 100644 --- a/src/BootstrapBlazor/Components/BaseComponents/BootstrapComponentBase.cs +++ b/src/BootstrapBlazor/Components/BaseComponents/BootstrapComponentBase.cs @@ -16,6 +16,7 @@ public abstract class BootstrapComponentBase : ComponentBase, IHandleEvent /// /// 获得/设置 用户自定义属性 /// Gets or sets user defined attributes + /// 10.2.2 /// [Parameter(CaptureUnmatchedValues = true)] [JsonIgnore] From 83e4fa46f3fdac1945a560c20b8e6aacacf0b606 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 22:12:02 +0800 Subject: [PATCH 11/22] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Components/AttributeTable.razor | 1 - src/BootstrapBlazor.Server/Data/AttributeItem.cs | 15 +-------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor index f7a92a984fe..c1a88173959 100644 --- a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor +++ b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor @@ -7,7 +7,6 @@ - diff --git a/src/BootstrapBlazor.Server/Data/AttributeItem.cs b/src/BootstrapBlazor.Server/Data/AttributeItem.cs index 2a9439617d9..3ce22fae117 100644 --- a/src/BootstrapBlazor.Server/Data/AttributeItem.cs +++ b/src/BootstrapBlazor.Server/Data/AttributeItem.cs @@ -1,10 +1,8 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License // See the LICENSE file in the project root for more information. // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone -using System.ComponentModel; - namespace BootstrapBlazor.Server.Data; /// @@ -15,36 +13,25 @@ public class AttributeItem /// /// 获得/设置 参数 /// - [DisplayName("参数")] public string Name { get; set; } = ""; /// /// 获得/设置 说明 /// - [DisplayName("说明")] public string Description { get; set; } = ""; /// /// 获得/设置 类型 /// - [DisplayName("类型")] public string Type { get; set; } = ""; /// /// 获得/设置 可选值 /// - [DisplayName("可选值")] public string ValueList { get; set; } = ""; - /// - /// 获得/设置 默认值 - /// - [DisplayName("默认值")] - public string DefaultValue { get; set; } = ""; - /// /// 获得/设置 版本 /// - [DisplayName("版本")] public string Version { get; set; } = ""; } From c0539cbe0f86d207031a3cf5673af06ea87dd0df Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 22:12:20 +0800 Subject: [PATCH 12/22] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=20xmlDoc?= =?UTF-8?q?=20=E5=A4=8D=E7=94=A8=E6=8F=90=E9=AB=98=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ComponentAttributeCacheService.cs | 92 ++++++++++--------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs index 65dbe9d9e01..079e5372d01 100644 --- a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs +++ b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs @@ -4,7 +4,6 @@ // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone using System.Collections.Concurrent; -using System.ComponentModel; using System.Reflection; using System.Xml; using System.Xml.Linq; @@ -16,29 +15,31 @@ namespace BootstrapBlazor.Server.Services; /// public static class ComponentAttributeCacheService { - private static readonly ConcurrentDictionary _cache = new(); + private static readonly ConcurrentDictionary _cache = new(); /// /// 获取组件的 AttributeItem 列表(带缓存) /// public static AttributeItem[] GetAttributes(Type componentType) { - return _cache.GetOrAdd(componentType, type => + var currentLanguage = System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; + var key = $"{componentType.FullName}_{currentLanguage}"; + return _cache.GetOrAdd(key, key => { var attributes = new List(); - var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance) + var properties = componentType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.GetCustomAttribute() != null); + var xmlDoc = GetXmlDocumentation(componentType.Assembly); foreach (var property in properties) { var item = new AttributeItem { Name = property.Name, Type = GetFriendlyTypeName(property.PropertyType), - Description = GetSummary(property) ?? "", - DefaultValue = GetDefaultValue(property) ?? "", + Description = GetSummary(xmlDoc, property) ?? "", ValueList = GetValueList(property) ?? "", - Version = GetVersion(property) ?? "" + Version = GetVersion(xmlDoc, property) ?? "" }; attributes.Add(item); } @@ -48,61 +49,70 @@ public static AttributeItem[] GetAttributes(Type componentType) } /// - /// 从 XML 注释获取 summary + /// 从 XML 注释获取 summary(支持多语言) /// - private static string? GetSummary(PropertyInfo property) + private static string? GetSummary(XDocument? xmlDoc, PropertyInfo property) { - var xmlDoc = GetXmlDocumentation(property.DeclaringType?.Assembly); if (xmlDoc == null) return null; var memberName = $"P:{property.DeclaringType?.FullName}.{property.Name}"; - var element = xmlDoc.Descendants("member") + var memberElement = xmlDoc.Descendants("member") .FirstOrDefault(x => x.Attribute("name")?.Value == memberName); - return element?.Element("summary")?.Value.Trim(); - } + if (memberElement == null) return null; - /// - /// 从 XML 注释的 para version 节点获取版本信息 - /// - private static string? GetVersion(PropertyInfo property) - { - var xmlDoc = GetXmlDocumentation(property.DeclaringType?.Assembly); - if (xmlDoc == null) return null; + var summaryElement = memberElement.Element("summary"); + if (summaryElement == null) return null; - var memberName = $"P:{property.DeclaringType?.FullName}.{property.Name}"; - var element = xmlDoc.Descendants("member") - .FirstOrDefault(x => x.Attribute("name")?.Value == memberName); + // 获取当前语言(zh-CN -> zh, en-US -> en) + var currentLanguage = System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; + + // 查找匹配当前语言的 para 元素 + var langPara = summaryElement.Elements("para") + .FirstOrDefault(p => p.Attribute("lang")?.Value == currentLanguage); - // 查找 10.0.0 - var versionElement = element?.Descendants("para") - .SelectMany(p => p.Elements("version")) - .FirstOrDefault(); + if (langPara != null) + { + return langPara.Value.Trim(); + } - return versionElement?.Value.Trim(); + // 如果找不到当前语言,回退到第一个有 lang 属性的 para(通常是 zh) + var firstLangPara = summaryElement.Elements("para") + .FirstOrDefault(p => p.Attribute("lang") != null); + + if (firstLangPara != null) + { + return firstLangPara.Value.Trim(); + } + + // 如果都没有,返回整个 summary 的文本(向后兼容旧格式) + return summaryElement.Value.Trim(); } /// - /// 获取默认值 + /// 从 XML 注释的 para version 节点获取版本信息 /// - private static string? GetDefaultValue(PropertyInfo property) + private static string? GetVersion(XDocument? xmlDoc, PropertyInfo property) { - var defaultValueAttr = property.GetCustomAttribute(); - if (defaultValueAttr != null) - { - return defaultValueAttr.Value?.ToString() ?? ""; - } - - // 从 XML 注释中提取 DefaultValue - var xmlDoc = GetXmlDocumentation(property.DeclaringType?.Assembly); if (xmlDoc == null) return null; var memberName = $"P:{property.DeclaringType?.FullName}.{property.Name}"; - var element = xmlDoc.Descendants("member") + var memberElement = xmlDoc.Descendants("member") .FirstOrDefault(x => x.Attribute("name")?.Value == memberName); - var defaultElement = element?.Element("value"); - return defaultElement?.Value.Trim(); + if (memberElement == null) return null; + + // 在 summary 节点下查找包含 version 的 para 节点 + // XML 格式: 10.2.2 + var summaryElement = memberElement.Element("summary"); + if (summaryElement == null) return null; + + // 查找第一个包含 version 元素的 para + // 直接在循环中返回,避免创建中间变量 + return summaryElement.Elements("para") + .Select(p => p.Element("version")) + .FirstOrDefault(v => v != null) + ?.Value.Trim(); } /// From 61c7da5c2f3312834c0f0fa3779028db97770a7b Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 22:13:23 +0800 Subject: [PATCH 13/22] =?UTF-8?q?refactor:=20=E5=85=BC=E5=AE=B9=E8=80=81?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Data/AttributeItem.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/BootstrapBlazor.Server/Data/AttributeItem.cs b/src/BootstrapBlazor.Server/Data/AttributeItem.cs index 3ce22fae117..e761968fd09 100644 --- a/src/BootstrapBlazor.Server/Data/AttributeItem.cs +++ b/src/BootstrapBlazor.Server/Data/AttributeItem.cs @@ -34,4 +34,9 @@ public class AttributeItem /// 获得/设置 版本 /// public string Version { get; set; } = ""; + + /// + /// + /// + public string DefaultValue { get; set; } = ""; } From ce8a596002398ef3a1c9dee6a941e8ab994c9622 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 22:21:10 +0800 Subject: [PATCH 14/22] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=20ValueLis?= =?UTF-8?q?t=20=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/AttributeTable.razor | 1 - .../ComponentAttributeCacheService.cs | 22 ++++--------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor index c1a88173959..8507e1486d9 100644 --- a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor +++ b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor @@ -6,7 +6,6 @@ - diff --git a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs index 079e5372d01..0bed0ff5c7b 100644 --- a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs +++ b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs @@ -4,6 +4,7 @@ // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone using System.Collections.Concurrent; +using System.Globalization; using System.Reflection; using System.Xml; using System.Xml.Linq; @@ -22,9 +23,9 @@ public static class ComponentAttributeCacheService /// public static AttributeItem[] GetAttributes(Type componentType) { - var currentLanguage = System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; + var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; var key = $"{componentType.FullName}_{currentLanguage}"; - return _cache.GetOrAdd(key, key => + return _cache.GetOrAdd(key, _ => { var attributes = new List(); var properties = componentType.GetProperties(BindingFlags.Public | BindingFlags.Instance) @@ -38,7 +39,6 @@ public static AttributeItem[] GetAttributes(Type componentType) Name = property.Name, Type = GetFriendlyTypeName(property.PropertyType), Description = GetSummary(xmlDoc, property) ?? "", - ValueList = GetValueList(property) ?? "", Version = GetVersion(xmlDoc, property) ?? "" }; attributes.Add(item); @@ -65,7 +65,7 @@ public static AttributeItem[] GetAttributes(Type componentType) if (summaryElement == null) return null; // 获取当前语言(zh-CN -> zh, en-US -> en) - var currentLanguage = System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; + var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; // 查找匹配当前语言的 para 元素 var langPara = summaryElement.Elements("para") @@ -115,20 +115,6 @@ public static AttributeItem[] GetAttributes(Type componentType) ?.Value.Trim(); } - /// - /// 获取可选值列表 - /// - private static string? GetValueList(PropertyInfo property) - { - // 如果是枚举类型,返回枚举值 - if (property.PropertyType.IsEnum) - { - return string.Join("/", Enum.GetNames(property.PropertyType)); - } - - return null; - } - /// /// 获取友好的类型名称 /// From de9218a548142e2af3cebd9c81fea16d054ba703 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 22:25:22 +0800 Subject: [PATCH 15/22] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=E8=AF=B4?= =?UTF-8?q?=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Components/AttributeTable.razor.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs index 943ececb22b..ea54cb8549b 100644 --- a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs @@ -6,7 +6,7 @@ namespace BootstrapBlazor.Server.Components.Components; /// -/// +/// 组件参数表格组件 /// public sealed partial class AttributeTable { @@ -15,25 +15,25 @@ public sealed partial class AttributeTable private IStringLocalizer? Localizer { get; set; } /// - /// + /// 获得/设置 表格标题 /// [Parameter] [NotNull] public string? Title { get; set; } /// - /// + /// 获得/设置 表格数据 /// [Parameter] public IEnumerable? Items { get; set; } /// - /// + /// 获得/设置 表格关联组件类型 /// [Parameter] public Type? Type { get; set; } /// - /// OnInitialized 方法 + /// /// protected override void OnInitialized() { From 1d783ddad016facff25272bd4a01108feb74ab23 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 22:25:35 +0800 Subject: [PATCH 16/22] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=94=B9=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=B1=BB=E5=9E=8B=E4=B8=BA=20List?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/ComponentAttributeCacheService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs index 0bed0ff5c7b..42ac9d01486 100644 --- a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs +++ b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs @@ -16,12 +16,12 @@ namespace BootstrapBlazor.Server.Services; /// public static class ComponentAttributeCacheService { - private static readonly ConcurrentDictionary _cache = new(); + private static readonly ConcurrentDictionary> _cache = new(); /// /// 获取组件的 AttributeItem 列表(带缓存) /// - public static AttributeItem[] GetAttributes(Type componentType) + public static List GetAttributes(Type componentType) { var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; var key = $"{componentType.FullName}_{currentLanguage}"; @@ -44,7 +44,7 @@ public static AttributeItem[] GetAttributes(Type componentType) attributes.Add(item); } - return attributes.ToArray(); + return attributes; }); } From b752f18137ee5fc6b7f384a5c82aabdb563afc1f Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 22:25:44 +0800 Subject: [PATCH 17/22] =?UTF-8?q?refactor:=20=E7=B2=BE=E7=AE=80=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Samples/Circles.razor.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/Circles.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Circles.razor.cs index cd3da7da243..c0c58581cd3 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Circles.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Circles.razor.cs @@ -1,10 +1,8 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License // See the LICENSE file in the project root for more information. // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone -using BootstrapBlazor.Server.Services; - namespace BootstrapBlazor.Server.Components.Samples; /// @@ -19,15 +17,5 @@ private void Add(int interval) _circleValue += interval; _circleValue = Math.Min(100, Math.Max(0, _circleValue)); } - - /// - /// GetAttributes - 使用反射和缓存自动获取 Circle 组件属性 - /// - /// - private AttributeItem[] GetAttributes() - { - // 通过示例组件名称 Circles 确定组件类型为 Circle - return ComponentAttributeCacheService.GetAttributes(typeof(BootstrapBlazor.Components.Circle)); - } } From 9daa6d7823990185cbcb169a6bbf35719318dbc3 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Fri, 16 Jan 2026 22:29:28 +0800 Subject: [PATCH 18/22] =?UTF-8?q?chore:=20=E4=B8=B4=E6=97=B6=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Directory.Build.targets | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/BootstrapBlazor.Server/Directory.Build.targets b/src/BootstrapBlazor.Server/Directory.Build.targets index c3c44e60247..37deb7fc1af 100644 --- a/src/BootstrapBlazor.Server/Directory.Build.targets +++ b/src/BootstrapBlazor.Server/Directory.Build.targets @@ -1,5 +1,13 @@ + + + + + + + + From 5ba8fac3892feb87fec9125c89ec03b7550052e3 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 17 Jan 2026 13:35:13 +0800 Subject: [PATCH 19/22] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/AttributeTable.razor | 6 ++- .../Components/AttributeTable.razor.cs | 11 ++++- .../ComponentAttributeCacheService.cs | 45 ++++++++++--------- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor index 8507e1486d9..adeda25536b 100644 --- a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor +++ b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor @@ -1,12 +1,16 @@

@Title

- +
+ + + +
diff --git a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs index ea54cb8549b..3f4b848654e 100644 --- a/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Components/AttributeTable.razor.cs @@ -24,7 +24,8 @@ public sealed partial class AttributeTable /// /// 获得/设置 表格数据 /// - [Parameter] public IEnumerable? Items { get; set; } + [Parameter] + public IEnumerable Items { get; set; } = []; /// /// 获得/设置 表格关联组件类型 @@ -32,6 +33,12 @@ public sealed partial class AttributeTable [Parameter] public Type? Type { get; set; } + /// + /// 是否显示合计信息 默认 false + /// + [Parameter] + public bool ShowFooter { get; set; } + /// /// /// @@ -41,7 +48,7 @@ protected override void OnInitialized() Title ??= Localizer[nameof(Title)]; - if (Items == null && Type != null) + if (Type != null) { Items = ComponentAttributeCacheService.GetAttributes(Type); } diff --git a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs index 42ac9d01486..b7cb7406b85 100644 --- a/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs +++ b/src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs @@ -19,33 +19,38 @@ public static class ComponentAttributeCacheService private static readonly ConcurrentDictionary> _cache = new(); /// - /// 获取组件的 AttributeItem 列表(带缓存) + /// 通过组件类型获取组件的 AttributeItem 列表 /// public static List GetAttributes(Type componentType) { +#if DEBUG + return GetAttributeCore(componentType); +#else var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; var key = $"{componentType.FullName}_{currentLanguage}"; - return _cache.GetOrAdd(key, _ => - { - var attributes = new List(); - var properties = componentType.GetProperties(BindingFlags.Public | BindingFlags.Instance) - .Where(p => p.GetCustomAttribute() != null); + return _cache.GetOrAdd(key, _ => GetAttributeCore(componentType)); +#endif + } - var xmlDoc = GetXmlDocumentation(componentType.Assembly); - foreach (var property in properties) - { - var item = new AttributeItem - { - Name = property.Name, - Type = GetFriendlyTypeName(property.PropertyType), - Description = GetSummary(xmlDoc, property) ?? "", - Version = GetVersion(xmlDoc, property) ?? "" - }; - attributes.Add(item); - } + private static List GetAttributeCore(Type type) + { + var attributes = new List(); + var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance) + .Where(p => p.GetCustomAttribute() != null); - return attributes; - }); + var xmlDoc = GetXmlDocumentation(type.Assembly); + foreach (var property in properties) + { + var item = new AttributeItem + { + Name = property.Name, + Type = GetFriendlyTypeName(property.PropertyType), + Description = GetSummary(xmlDoc, property) ?? "", + Version = GetVersion(xmlDoc, property) ?? "10.0.0" + }; + attributes.Add(item); + } + return attributes.OrderBy(i => i.Name).ToList(); } /// From b46e1a6161d127cfb4ac325ae20193d23af863bb Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 17 Jan 2026 13:37:54 +0800 Subject: [PATCH 20/22] =?UTF-8?q?refactor:=20=E8=B0=83=E6=95=B4=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Directory.Build.targets | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/BootstrapBlazor.Server/Directory.Build.targets b/src/BootstrapBlazor.Server/Directory.Build.targets index 37deb7fc1af..c3c44e60247 100644 --- a/src/BootstrapBlazor.Server/Directory.Build.targets +++ b/src/BootstrapBlazor.Server/Directory.Build.targets @@ -1,13 +1,5 @@ - - - - - - - - From 9c0ecdefdfc11673e61849c2aa034cd2ce11fc74 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 17 Jan 2026 13:39:04 +0800 Subject: [PATCH 21/22] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Directory.Build.targets | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/BootstrapBlazor.Server/Directory.Build.targets b/src/BootstrapBlazor.Server/Directory.Build.targets index c3c44e60247..4beb8250df6 100644 --- a/src/BootstrapBlazor.Server/Directory.Build.targets +++ b/src/BootstrapBlazor.Server/Directory.Build.targets @@ -1,6 +1,12 @@ - + + + + + + + @@ -8,10 +14,4 @@ - - - - - - From 6c8cf2be57640e7def59703072fbbd4d4a5c16e7 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 17 Jan 2026 13:42:06 +0800 Subject: [PATCH 22/22] =?UTF-8?q?chore:=20=E6=92=A4=E9=94=80=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/BaseComponents/BootstrapComponentBase.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/BootstrapBlazor/Components/BaseComponents/BootstrapComponentBase.cs b/src/BootstrapBlazor/Components/BaseComponents/BootstrapComponentBase.cs index 87a2255f2d9..22fdcee4abf 100644 --- a/src/BootstrapBlazor/Components/BaseComponents/BootstrapComponentBase.cs +++ b/src/BootstrapBlazor/Components/BaseComponents/BootstrapComponentBase.cs @@ -16,7 +16,6 @@ public abstract class BootstrapComponentBase : ComponentBase, IHandleEvent /// /// 获得/设置 用户自定义属性 /// Gets or sets user defined attributes - /// 10.2.2 /// [Parameter(CaptureUnmatchedValues = true)] [JsonIgnore]