Skip to content
5 changes: 0 additions & 5 deletions src/BootstrapBlazor.Server/Components/Samples/Ajaxs.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ class User
private Task Goto() => AjaxService.Goto("/introduction");

private Task GotoSelf() => AjaxService.Goto("/ajax");

/// <summary>
/// 获得属性方法
/// </summary>
/// <returns></returns>
private List<MethodItem> GetMethods() =>
[
new()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public partial class CheckboxLists
EnumEducation.Middle, EnumEducation.Primary
};


[NotNull]
private IEnumerable<SelectedItem>? Items1 { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public partial class EmbedPdfs
private EmbedPDFTheme _theme = EmbedPDFTheme.System;
private EmbedPDFScrollStrategy _strategy = EmbedPDFScrollStrategy.Vertical;
private string _url = "./samples/sample.pdf";
private string _streamFileName = "";
private string _language = "";

private List<SelectedItem> _languages = new List<SelectedItem>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public partial class FlipClocks

private string CardGroupMarginValueString => $"{CardGroupMarginValue}px";


private bool _isCompleted;
private bool _showYear = false;
private bool _showMonth = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ private static string FormatResult(TranslationText translation)
var culture = new CultureInfo(translation.TargetLanguage);
return $"{culture.NativeName}: {translation.Text}";
}

/// <summary>
/// 获得属性方法
/// </summary>
/// <returns></returns>
protected MethodItem[] GetMethods() =>
[
new()
Expand Down
12 changes: 6 additions & 6 deletions src/BootstrapBlazor.Server/Data/AttributeItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,32 @@ public class AttributeItem
/// <summary>
/// 获得/设置 参数
/// </summary>
public string Name { get; set; } = "";
public string? Name { get; set; }

/// <summary>
/// 获得/设置 说明
/// </summary>
public string Description { get; set; } = "";
public string? Description { get; set; }

/// <summary>
/// 获得/设置 类型
/// </summary>
public string Type { get; set; } = "";
public string? Type { get; set; }

/// <summary>
/// 获得/设置 可选值
/// </summary>
public string ValueList { get; set; } = "";
public string? ValueList { get; set; }

/// <summary>
/// 获得/设置 版本
/// </summary>
public string Version { get; set; } = "10.2.2";
public string? Version { get; set; }

/// <summary>
/// 获得/设置 默认值
/// </summary>
public string DefaultValue { get; set; } = "";
public string? DefaultValue { get; set; }
Comment on lines +16 to +41
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AttributeItem properties changed from non-nullable strings with default values to nullable strings. This is a breaking change if any code relies on these properties never being null. Consumers of AttributeItem may now need to handle null values, which could lead to NullReferenceExceptions if not properly handled in UI rendering code.

Copilot uses AI. Check for mistakes.

/// <summary>
/// 获得/设置 是否已弃用
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public static class ComponentAttributeCacheService
{
private static readonly ConcurrentDictionary<string, List<AttributeItem>> _cache = new();

private static XDocument? _xmlDoc;

/// <summary>
/// 通过组件类型获取组件的 AttributeItem 列表
/// </summary>
Expand All @@ -43,13 +45,21 @@ private static List<AttributeItem> GetAttributeCore(Type type)
.ToArray();
}

var xmlDoc = GetXmlDocumentation(type.Assembly);
// 获得 BootstrapBlazor 程序集 xml 文档
_xmlDoc ??= GetXmlDocumentation(typeof(BootstrapBlazorRoot).Assembly);
XDocument? xmlDoc = null;
if (type.Assembly.GetName().Name != "BootstrapBlazor")
{
// 扩展组件包
xmlDoc = GetXmlDocumentation(type.Assembly);
}

return properties.Select(property => new AttributeItem
{
Name = property.Name,
Type = GetFriendlyTypeName(property.PropertyType),
Description = GetSummary(xmlDoc, property) ?? "",
Version = GetVersion(xmlDoc, property) ?? "10.0.0",
Version = GetVersion(xmlDoc, property),
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Version property now returns null when xmlDoc is null or when no version is found. Previously, the code had a fallback to "10.0.0" on line 62 of the old code. Removing this default could result in null Version values being displayed in the attribute table. This may be intentional if you want to distinguish between components with and without explicit version info, but it's a behavioral change that should be considered.

Suggested change
Version = GetVersion(xmlDoc, property),
Version = GetVersion(xmlDoc, property) ?? "10.0.0",

Copilot uses AI. Check for mistakes.
IsObsolete = property.GetCustomAttribute<ObsoleteAttribute>() != null
}).OrderBy(i => i.Name).ToList();
}
Expand All @@ -59,18 +69,19 @@ private static List<AttributeItem> GetAttributeCore(Type type)
/// </summary>
private static string? GetSummary(XDocument? xmlDoc, PropertyInfo property)
{
if (xmlDoc == null) return null;

var type = property.DeclaringType ?? property.PropertyType;
var typeName = type.FullName ?? $"BootstrapBlazor.Components.{type.Name}";
var typeName = $"BootstrapBlazor.Components.{type.Name}";
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 73 hardcodes the namespace as "BootstrapBlazor.Components" but this assumes all types are in this namespace. The previous code used type.FullName ?? $"BootstrapBlazor.Components.{type.Name}" which was more flexible. For extension assemblies or types in different namespaces, this hardcoded approach could fail to find the correct XML documentation member name.

Suggested change
var typeName = $"BootstrapBlazor.Components.{type.Name}";
var typeName = type.FullName ?? $"BootstrapBlazor.Components.{type.Name}";

Copilot uses AI. Check for mistakes.
var memberName = $"P:{typeName}.{property.Name}";
var summaryElement = FindSummaryElement(xmlDoc, memberName);
return summaryElement == null ? null : GetLocalizedSummary(summaryElement);
}

private static XElement? FindSummaryElement(XDocument xmlDoc, string memberName)
private static XElement? FindSummaryElement(XDocument? xmlDoc, string memberName)
{
var memberElement = xmlDoc.Descendants("member")
// 如果 xmlDoc 为空表示为 BootstrapBlazor 组件
var memberElement = xmlDoc?.Descendants("member")
.FirstOrDefault(x => x.Attribute("name")?.Value == memberName)
?? _xmlDoc?.Descendants("member")
.FirstOrDefault(x => x.Attribute("name")?.Value == memberName);

var summaryElement = memberElement?.Element("summary");
Expand All @@ -79,8 +90,8 @@ private static List<AttributeItem> GetAttributeCore(Type type)
return null;
}

var doc = summaryElement.Element("inheritdoc")?.Attribute("cref")?.Value;
return doc != null ? FindSummaryElement(xmlDoc, doc) : summaryElement;
var v = summaryElement.Element("inheritdoc")?.Attribute("cref")?.Value;
return v != null ? FindSummaryElement(xmlDoc, v) : summaryElement;
Comment on lines +93 to +94
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable name 'v' is not descriptive. It's used to store the inheritdoc reference value. Consider renaming to something more meaningful like 'inheritdocRef' or 'cref' to improve code readability.

Suggested change
var v = summaryElement.Element("inheritdoc")?.Attribute("cref")?.Value;
return v != null ? FindSummaryElement(xmlDoc, v) : summaryElement;
var inheritdocRef = summaryElement.Element("inheritdoc")?.Attribute("cref")?.Value;
return inheritdocRef != null ? FindSummaryElement(xmlDoc, inheritdocRef) : summaryElement;

Copilot uses AI. Check for mistakes.
}

private static string? GetLocalizedSummary(XElement? summaryElement)
Expand Down
Loading
Loading