diff --git a/src/BootstrapBlazor.Shared/Locales/en.json b/src/BootstrapBlazor.Shared/Locales/en.json
index aa2b144fb..22d8cb036 100644
--- a/src/BootstrapBlazor.Shared/Locales/en.json
+++ b/src/BootstrapBlazor.Shared/Locales/en.json
@@ -424,18 +424,19 @@
"Introduce": "Added component ErrorLogger
Through this component, global logs and exceptions can be output uniformly; currently, the Blazor
framework does not provide a MVC
like < b>Global exception The overall solution, for the time being, you need to use try/catch
in the code block for exception capture",
"H1": "Instructions",
"Step1": "1. Add AddLogging
to the Startup
file to enable the net core
system log function",
- "Step1Introduce": "使用 AddFileLogger
需要引用 Longbow.Logging 组件包",
+ "Step1Introduce": "Use AddFileLogger
need to reference Longbow.Logging component package",
"Step2": "2. Use BlazorLogger
to wrap the content, such as: Body
in MainLayout
",
"Step3": "3. Use cascading parameters in the code to get examples",
"Step4": "4. Console or IIS output visible log information",
- "Step5": "5. 控制是否显示错误明细信息",
- "Step5Intro": "通过配置文件 appsettings.json
,开发环境下为 appsettings.Development.json
,未设置时默认为 false
不显示,默认行为仅做弹窗提示防止敏感信息暴露",
+ "Step5": "5. Controls whether error details are displayed",
+ "Step5Intro": "Through the configuration file appsettings.json
, which is appsettings.Development.json
in the development environment, if not set, it defaults to false
and is not displayed. The default behavior is only a pop-up prompt to prevent the exposure of sensitive information",
"Block1Title": "Test",
"Block1Intro": "This function is to obtain the component instance through the cascade parameter and use its function",
"ExceptionTestIntroduce": "In this example code, an error code that divides by zero is written. Because try/catch
is used to capture the exception, the error message is displayed in the console below",
"ButtonText": "test",
- "Block2Title": "自定义错误处理",
- "Block2Intro": "通过设置 OnErrorHandleAsync
回调方法,设置自定义异常处理逻辑"
+ "Block2Title": "OnErrorHandleAsync",
+ "Block2Intro": "Set custom exception handling logic by setting OnErrorHandleAsync
callback method",
+ "Tips": "Both the Layout
component and the Tab
component have built-in ErrorLogger
components. Please do not add them in the above two components. The following is the simplified example code"
},
"BootstrapBlazor.Shared.Samples.Splits": {
"Title": "Split",
diff --git a/src/BootstrapBlazor.Shared/Locales/zh.json b/src/BootstrapBlazor.Shared/Locales/zh.json
index fdf0f5b93..336df51d4 100644
--- a/src/BootstrapBlazor.Shared/Locales/zh.json
+++ b/src/BootstrapBlazor.Shared/Locales/zh.json
@@ -435,7 +435,8 @@
"ExceptionTestIntroduce": "本例代码中写了一个除以零的错误代码,并且未使用 try/catch
对异常进行捕获,系统并不会崩溃导致不可用,
Debug
模式下会显示错误的 描述信息 与 堆栈信息Release
模式下默认使用 Toast
进行弹窗提示
可通过设置 ErrorContent
对 异常信息 进行自定义布局显示
",
"ButtonText": "测试",
"Block2Title": "自定义错误处理",
- "Block2Intro": "通过设置 OnErrorHandleAsync
回调方法,设置自定义异常处理逻辑"
+ "Block2Intro": "通过设置 OnErrorHandleAsync
回调方法,设置自定义异常处理逻辑",
+ "Tips": "Layout
组件与 Tab
组件均已内置 ErrorLogger
组件请勿在上述两个组件内额外添加使用,下面是精简后的示例代码"
},
"BootstrapBlazor.Shared.Samples.Splits": {
"Title": "Split 面板分割",
diff --git a/src/BootstrapBlazor.Shared/Samples/GlobalException.razor b/src/BootstrapBlazor.Shared/Samples/GlobalException.razor
index 68ef1447c..574364c65 100644
--- a/src/BootstrapBlazor.Shared/Samples/GlobalException.razor
+++ b/src/BootstrapBlazor.Shared/Samples/GlobalException.razor
@@ -68,4 +68,16 @@
+
+
+ @((MarkupString)Localizer["Tips"].Value)
+
+
+
+<Layout OnErrorHandleAsync="OnErrorHandleAsync">
+ <Main>
+ @@Body
+ </Main>
+</Layout>
+
diff --git a/src/BootstrapBlazor.Shared/Samples/Timelines.razor.cs b/src/BootstrapBlazor.Shared/Samples/Timelines.razor.cs
index 5e53954c5..86b31313d 100644
--- a/src/BootstrapBlazor.Shared/Samples/Timelines.razor.cs
+++ b/src/BootstrapBlazor.Shared/Samples/Timelines.razor.cs
@@ -8,271 +8,272 @@ using BootstrapBlazor.Shared.Components;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-namespace BootstrapBlazor.Shared.Samples
+namespace BootstrapBlazor.Shared.Samples;
+
+///
+///
+///
+public sealed partial class Timelines
{
+ private readonly ConcurrentQueue _messages = new();
+
+ private readonly CancellationTokenSource _cancelTokenSource = new();
+
+ private readonly AutoResetEvent _locker = new(true);
+
+ private IEnumerable Messages => _messages;
+
+ private bool IsReverse { get; set; }
+
+ private static Color GetColor()
+ {
+ var second = DateTime.Now.Second;
+ return (second % 3) switch
+ {
+ 1 => Color.Danger,
+ 2 => Color.Info,
+ _ => Color.None
+ };
+ }
+
///
///
///
- public sealed partial class Timelines
+ ///
+ protected override async Task OnInitializedAsync()
{
- private readonly ConcurrentQueue _messages = new();
+ await base.OnInitializedAsync();
- private readonly CancellationTokenSource _cancelTokenSource = new();
-
- private readonly AutoResetEvent _locker = new(true);
-
- private IEnumerable Messages => _messages;
-
- private bool IsReverse { get; set; }
-
- private static Color GetColor()
+ var _ = Task.Run(async () =>
{
- var second = DateTime.Now.Second;
- return (second % 3) switch
+ do
{
- 1 => Color.Danger,
- 2 => Color.Info,
- _ => Color.None
- };
- }
+ _locker.WaitOne();
+ _messages.Enqueue(new ConsoleMessageItem { Message = $"{DateTimeOffset.Now}: Dispatch Message", Color = GetColor() });
- ///
- ///
- ///
- ///
- protected override async Task OnInitializedAsync()
- {
- await base.OnInitializedAsync();
-
- var _ = Task.Run(async () =>
- {
- do
+ if (_messages.Count > 8)
{
- _locker.WaitOne();
- _messages.Enqueue(new ConsoleMessageItem { Message = $"{DateTimeOffset.Now}: Dispatch Message", Color = GetColor() });
-
- if (_messages.Count > 8)
- {
- _messages.TryDequeue(out var _);
- }
- await InvokeAsync(StateHasChanged);
- _locker.Set();
- await Task.Delay(2000, _cancelTokenSource.Token);
+ _messages.TryDequeue(out var _);
}
- while (!_cancelTokenSource.IsCancellationRequested);
- });
-
- Items = new SelectedItem[]
- {
- new SelectedItem("1",Localizer["SelectedItem1"]){ Active=true },
- new SelectedItem("2",Localizer["SelectedItem2"])
- };
- }
-
- ///
- ///
- ///
- ///
- ///
-
- public Task OnStateChanged(IEnumerable values, SelectedItem value)
- {
- IsReverse = value.Text == Localizer["SelectedItem2"];
- StateHasChanged();
- return Task.CompletedTask;
- }
-
- ///
- ///
- ///
- private IEnumerable Items { get; set; }
-
- ///
- ///
- ///
- private IEnumerable TimelineItems => new TimelineItem[]
- {
- new TimelineItem {
- Content = Localizer["TimelineItemContent1"],
- Description = DateTime.Now.ToString("yyyy-MM-dd")
- },
- new TimelineItem{
- Content = Localizer["TimelineItemContent2"],
- Description = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd")
- },
- new TimelineItem
- {
- Content = Localizer["TimelineItemContent3"],
- Description = DateTime.Now.AddDays(2).ToString("yyyy-MM-dd")
+ await InvokeAsync(StateHasChanged);
+ _locker.Set();
+ await Task.Delay(2000, _cancelTokenSource.Token);
}
- };
+ while (!_cancelTokenSource.IsCancellationRequested);
+ });
- ///
- ///
- ///
- private IEnumerable CustomerTimelineItems => new TimelineItem[]
+ Items = new SelectedItem[]
{
- new TimelineItem
- {
- Content = Localizer["TimelineItemContent4"],
- Description = DateTime.Now.ToString("yyyy-MM-dd")
- },
- new TimelineItem
- {
- Color = Color.Success,
- Content = Localizer["TimelineItemContent5"],
- Description = DateTime.Now.AddDays(2).ToString("yyyy-MM-dd")
- },
- new TimelineItem
- {
- Color = Color.Danger,
- Icon = "fa fa-fw fa-fa",
- Content = Localizer["TimelineItemContent6"],
- Description = DateTime.Now.AddDays(3).ToString("yyyy-MM-dd")
- }
- };
-
- ///
- ///
- ///
- private IEnumerable GetCustomerComponentTimelineItems() => new TimelineItem[]
- {
- new TimelineItem
- {
- Color = Color.Success,
- Component = BootstrapDynamicComponent.CreateComponent(new Dictionary
- {
- [nameof(BootstrapBlazor.Components.Console.Items)] = Messages
- }),
- Description = Localizer["Description1"]
- },
- new TimelineItem
- {
- Color = Color.Info,
- Component = BootstrapDynamicComponent.CreateComponent(),
- Description = Localizer["Description2"]
- },
- new TimelineItem
- {
- Color = Color.Warning,
- Component = BootstrapDynamicComponent.CreateComponent(),
- Description = Localizer["Description3"]
- }
- };
-
- ///
- ///
- ///
- private readonly IEnumerable AlternateTimelineItems = new TimelineItem[]
- {
- new TimelineItem
- {
- Content = "Create a services site 2015-09-01",
- },
- new TimelineItem
- {
- Color = Color.Success,
- Content = "Solve initial network problems 2015-09-01",
- },
- new TimelineItem
- {
- Color = Color.Danger,
- Content = "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.",
- },
- new TimelineItem
- {
- Color = Color.Warning,
- Content = "Network problems being solved 2015-09-01",
- },
- new TimelineItem
- {
- Color = Color.Info,
- Content = "Create a services site 2015-09-01",
- }
- };
-
- ///
- /// 获得属性方法
- ///
- ///
- private IEnumerable GetAttributes() => new AttributeItem[]
- {
- // TODO: 移动到数据库中
- new AttributeItem() {
- Name = "Items",
- Description = Localizer["Items"],
- Type = "IEnumerable",
- ValueList = "—",
- DefaultValue = " — "
- },
- new AttributeItem() {
- Name = "IsReverse",
- Description = Localizer["IsReverse"],
- Type = "boolean",
- ValueList = "true|false",
- DefaultValue = "false"
- },
- new AttributeItem() {
- Name = "IsLeft",
- Description = Localizer["IsLeft"],
- Type = "boolean",
- ValueList = "true|false",
- DefaultValue = "false"
- },
- new AttributeItem() {
- Name = "IsAlternate",
- Description = Localizer["IsAlternate"],
- Type = "boolean",
- ValueList = "true|false",
- DefaultValue = "false"
- },
- };
-
- ///
- /// 获得属性方法
- ///
- ///
- private IEnumerable GetTimelineItemAttributes() => new AttributeItem[]
- {
- // TODO: 移动到数据库中
- new AttributeItem() {
- Name = nameof(TimelineItem.Color),
- Description = Localizer["Color"],
- Type = "Color",
- ValueList = " — ",
- DefaultValue = " — "
- },
- new AttributeItem() {
- Name = nameof(TimelineItem.Content),
- Description = Localizer["Content"],
- Type = "string",
- ValueList = " — ",
- DefaultValue = " — "
- },
- new AttributeItem() {
- Name = nameof(TimelineItem.Icon),
- Description = Localizer["Icon"],
- Type = "string",
- ValueList = " — ",
- DefaultValue = " — "
- },
- new AttributeItem() {
- Name = nameof(TimelineItem.Description),
- Description = Localizer["Description"],
- Type = "string",
- ValueList = " — ",
- DefaultValue = " — "
- },
- new AttributeItem() {
- Name = nameof(TimelineItem.Component),
- Description = Localizer["Component"],
- Type = nameof(BootstrapDynamicComponent),
- ValueList = " — ",
- DefaultValue = " — "
- }
+ new SelectedItem("1", Localizer["SelectedItem1"]) { Active=true },
+ new SelectedItem("2", Localizer["SelectedItem2"])
};
}
+
+ ///
+ ///
+ ///
+ ///
+ ///
+
+ public Task OnStateChanged(IEnumerable values, SelectedItem value)
+ {
+ IsReverse = value.Text == Localizer["SelectedItem2"];
+ StateHasChanged();
+ return Task.CompletedTask;
+ }
+
+ ///
+ ///
+ ///
+ private IEnumerable Items { get; set; } = Enumerable.Empty();
+
+ ///
+ ///
+ ///
+ private IEnumerable TimelineItems => new TimelineItem[]
+ {
+ new TimelineItem
+ {
+ Content = Localizer["TimelineItemContent1"],
+ Description = DateTime.Now.ToString("yyyy-MM-dd")
+ },
+ new TimelineItem
+ {
+ Content = Localizer["TimelineItemContent2"],
+ Description = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd")
+ },
+ new TimelineItem
+ {
+ Content = Localizer["TimelineItemContent3"],
+ Description = DateTime.Now.AddDays(2).ToString("yyyy-MM-dd")
+ }
+ };
+
+ ///
+ ///
+ ///
+ private IEnumerable CustomerTimelineItems => new TimelineItem[]
+ {
+ new TimelineItem
+ {
+ Content = Localizer["TimelineItemContent4"],
+ Description = DateTime.Now.ToString("yyyy-MM-dd")
+ },
+ new TimelineItem
+ {
+ Color = Color.Success,
+ Content = Localizer["TimelineItemContent5"],
+ Description = DateTime.Now.AddDays(2).ToString("yyyy-MM-dd")
+ },
+ new TimelineItem
+ {
+ Color = Color.Danger,
+ Icon = "fa fa-fw fa-fa",
+ Content = Localizer["TimelineItemContent6"],
+ Description = DateTime.Now.AddDays(3).ToString("yyyy-MM-dd")
+ }
+ };
+
+ ///
+ ///
+ ///
+ private IEnumerable GetCustomerComponentTimelineItems() => new TimelineItem[]
+ {
+ new TimelineItem
+ {
+ Color = Color.Success,
+ Component = BootstrapDynamicComponent.CreateComponent(new Dictionary
+ {
+ [nameof(BootstrapBlazor.Components.Console.Items)] = Messages
+ }),
+ Description = Localizer["Description1"]
+ },
+ new TimelineItem
+ {
+ Color = Color.Info,
+ Component = BootstrapDynamicComponent.CreateComponent(),
+ Description = Localizer["Description2"]
+ },
+ new TimelineItem
+ {
+ Color = Color.Warning,
+ Component = BootstrapDynamicComponent.CreateComponent(),
+ Description = Localizer["Description3"]
+ }
+ };
+
+ ///
+ ///
+ ///
+ private readonly IEnumerable AlternateTimelineItems = new TimelineItem[]
+ {
+ new TimelineItem
+ {
+ Content = "Create a services site 2015-09-01",
+ },
+ new TimelineItem
+ {
+ Color = Color.Success,
+ Content = "Solve initial network problems 2015-09-01",
+ },
+ new TimelineItem
+ {
+ Color = Color.Danger,
+ Content = "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.",
+ },
+ new TimelineItem
+ {
+ Color = Color.Warning,
+ Content = "Network problems being solved 2015-09-01",
+ },
+ new TimelineItem
+ {
+ Color = Color.Info,
+ Content = "Create a services site 2015-09-01",
+ }
+ };
+
+ ///
+ /// 获得属性方法
+ ///
+ ///
+ private IEnumerable GetAttributes() => new AttributeItem[]
+ {
+ // TODO: 移动到数据库中
+ new AttributeItem() {
+ Name = "Items",
+ Description = Localizer["Items"],
+ Type = "IEnumerable",
+ ValueList = "—",
+ DefaultValue = " — "
+ },
+ new AttributeItem() {
+ Name = "IsReverse",
+ Description = Localizer["IsReverse"],
+ Type = "boolean",
+ ValueList = "true|false",
+ DefaultValue = "false"
+ },
+ new AttributeItem() {
+ Name = "IsLeft",
+ Description = Localizer["IsLeft"],
+ Type = "boolean",
+ ValueList = "true|false",
+ DefaultValue = "false"
+ },
+ new AttributeItem() {
+ Name = "IsAlternate",
+ Description = Localizer["IsAlternate"],
+ Type = "boolean",
+ ValueList = "true|false",
+ DefaultValue = "false"
+ }
+ };
+
+ ///
+ /// 获得属性方法
+ ///
+ ///
+ private IEnumerable GetTimelineItemAttributes() => new AttributeItem[]
+ {
+ new AttributeItem() {
+ Name = nameof(TimelineItem.Color),
+ Description = Localizer["Color"],
+ Type = "Color",
+ ValueList = " — ",
+ DefaultValue = " — "
+ },
+ new AttributeItem() {
+ Name = nameof(TimelineItem.Content),
+ Description = Localizer["Content"],
+ Type = "string",
+ ValueList = " — ",
+ DefaultValue = " — "
+ },
+ new AttributeItem() {
+ Name = nameof(TimelineItem.Icon),
+ Description = Localizer["Icon"],
+ Type = "string",
+ ValueList = " — ",
+ DefaultValue = " — "
+ },
+ new AttributeItem() {
+ Name = nameof(TimelineItem.Description),
+ Description = Localizer["Description"],
+ Type = "string",
+ ValueList = " — ",
+ DefaultValue = " — "
+ },
+ new AttributeItem() {
+ Name = nameof(TimelineItem.Component),
+ Description = Localizer["Component"],
+ Type = nameof(BootstrapDynamicComponent),
+ ValueList = " — ",
+ DefaultValue = " — "
+ }
+ };
}