From 18ab161d0c3d79c26f83cd1b88d9e07278329ea8 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 19 Feb 2025 18:37:39 +0800 Subject: [PATCH 01/20] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20enableIpLoca?= =?UTF-8?q?tor=20=E5=8F=82=E6=95=B0=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/wwwroot/modules/hub.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BootstrapBlazor/wwwroot/modules/hub.js b/src/BootstrapBlazor/wwwroot/modules/hub.js index ac0923bbd8c..95602948d2b 100644 --- a/src/BootstrapBlazor/wwwroot/modules/hub.js +++ b/src/BootstrapBlazor/wwwroot/modules/hub.js @@ -3,7 +3,7 @@ import Data from "./data.js" import EventHandler from "./event-handler.js"; export async function init(id, options) { - const { invoke, method, interval = 3000, url, connectionId } = options; + const { invoke, method, interval = 3000, url, connectionId, enableIpLocator } = options; const elKey = 'bb_hub_el_id'; if (localStorage.getItem(elKey) === null) { localStorage.setItem(elKey, id); @@ -34,7 +34,7 @@ export async function init(id, options) { } }); - const info = await getClientInfo(url); + const info = await getClientInfo(url, { enableIpLocator: enableIpLocator }); info.id = clientId; const callback = async () => { From ba712ebe000e9272848c2467920585bb05c39b5a Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 19 Feb 2025 18:38:04 +0800 Subject: [PATCH 02/20] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=A6=81?= =?UTF-8?q?=E6=AD=A2=E8=B0=83=E7=94=A8=20ip.axd=20=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/wwwroot/modules/client.js | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/BootstrapBlazor/wwwroot/modules/client.js b/src/BootstrapBlazor/wwwroot/modules/client.js index a608d7b9090..73bdab42dde 100644 --- a/src/BootstrapBlazor/wwwroot/modules/client.js +++ b/src/BootstrapBlazor/wwwroot/modules/client.js @@ -1,12 +1,12 @@ import "./browser.js" import { execute } from "./ajax.js" -export async function ping(url, invoke, method) { - const data = await getClientInfo(url); +export async function ping(url, invoke, method, options) { + const data = await getClientInfo(url, options); await invoke.invokeMethodAsync(method, data) } -export async function getClientInfo(url) { +export async function getClientInfo(url, options) { const info = browser() let data = { browser: info.browser + ' ' + info.version, @@ -17,12 +17,14 @@ export async function getClientInfo(url) { os: info.system + ' ' + info.systemVersion } - const result = await execute({ - method: 'GET', - url - }); - if (result) { - data.ip = result.Ip; + if (options.enableIpLocator === true) { + const result = await execute({ + method: 'GET', + url + }); + if (result) { + data.ip = result.Ip; + } } data.id = localStorage.getItem('bb_hub_connection_id') ?? result.Id; return data; From 455466772fc3aca049f78a2e178e0b566626aad7 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 19 Feb 2025 18:38:27 +0800 Subject: [PATCH 03/20] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=20EnableIp?= =?UTF-8?q?Locator=20=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/ConnectionHub/ConnectionHub.cs | 3 ++- src/BootstrapBlazor/Services/WebClientService.cs | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/BootstrapBlazor/Components/ConnectionHub/ConnectionHub.cs b/src/BootstrapBlazor/Components/ConnectionHub/ConnectionHub.cs index 57114bf3447..e6961bc3989 100644 --- a/src/BootstrapBlazor/Components/ConnectionHub/ConnectionHub.cs +++ b/src/BootstrapBlazor/Components/ConnectionHub/ConnectionHub.cs @@ -51,7 +51,8 @@ protected override async Task InvokeInitAsync() Method = nameof(Callback), ConnectionId = Guid.NewGuid(), Interval = options.BeatInterval.TotalMilliseconds, - Url = "ip.axd" + Url = "ip.axd", + BootstrapBlazorOptions.Value.WebClientOptions.EnableIpLocator }); } } diff --git a/src/BootstrapBlazor/Services/WebClientService.cs b/src/BootstrapBlazor/Services/WebClientService.cs index d545a21967b..5512100f1e9 100644 --- a/src/BootstrapBlazor/Services/WebClientService.cs +++ b/src/BootstrapBlazor/Services/WebClientService.cs @@ -44,7 +44,10 @@ public async Task GetClientInfo() { _jsModule ??= await runtime.LoadModuleByName("client"); _interop ??= DotNetObjectReference.Create(this); - await _jsModule.InvokeVoidAsync("ping", "ip.axd", _interop, nameof(SetData)); + await _jsModule.InvokeVoidAsync("ping", "ip.axd", _interop, nameof(SetData), new + { + options.CurrentValue.WebClientOptions.EnableIpLocator + }); // 等待 SetData 方法执行完毕 await _taskCompletionSource.Task.WaitAsync(TimeSpan.FromSeconds(3)); From 1104e7a652621d0733164ad6bb78c98fa61d6dd1 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 19 Feb 2025 18:38:58 +0800 Subject: [PATCH 04/20] chore: bump version 9.3.1-beta23 --- src/BootstrapBlazor/BootstrapBlazor.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 211ed6d61ac..86ee6197a7c 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@ - 9.3.1-beta22 + 9.3.1-beta23 From c813c647603d31e17c9b9889194133dbb3200169 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 10:34:41 +0800 Subject: [PATCH 05/20] =?UTF-8?q?refactor:=20=E4=BB=A3=E7=A0=81=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Samples/Locators.razor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/Locators.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Locators.razor.cs index 33e2bf80f14..e23fcf5c642 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Locators.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Locators.razor.cs @@ -42,11 +42,11 @@ protected override void OnInitialized() { base.OnInitialized(); - _providers = IpLocatorProviders.Select(provider => new SelectedItem + _providers = [.. IpLocatorProviders.Select(provider => new SelectedItem { Text = provider.GetType().Name, Value = provider.GetType().Name - }).ToList(); + })]; } /// From 06d07f0cb93738c2459eca0a73a7b5ab93d60334 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 10:35:01 +0800 Subject: [PATCH 06/20] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=E4=B8=8D?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/BootstrapBlazor.Server/Program.cs b/src/BootstrapBlazor.Server/Program.cs index f8cb21106db..5e9a3610256 100644 --- a/src/BootstrapBlazor.Server/Program.cs +++ b/src/BootstrapBlazor.Server/Program.cs @@ -4,7 +4,6 @@ // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone using BootstrapBlazor.Server.Components; -using BootstrapBlazor.Server.Components.Layout; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.Extensions.Options; using System.Text; From 021e135a5e10b46245f58ff01866d3bf90e4624e Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 10:35:20 +0800 Subject: [PATCH 07/20] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=A6=BB?= =?UTF-8?q?=E7=BA=BF=20IP=20=E5=9C=B0=E7=90=86=E4=BD=8D=E7=BD=AE=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/ServiceCollectionSharedExtensions.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/BootstrapBlazor.Server/Extensions/ServiceCollectionSharedExtensions.cs b/src/BootstrapBlazor.Server/Extensions/ServiceCollectionSharedExtensions.cs index c577d8f696b..479c7981f93 100644 --- a/src/BootstrapBlazor.Server/Extensions/ServiceCollectionSharedExtensions.cs +++ b/src/BootstrapBlazor.Server/Extensions/ServiceCollectionSharedExtensions.cs @@ -79,6 +79,9 @@ public static IServiceCollection AddBootstrapBlazorServices(this IServiceCollect // 增加 Table Excel 导出服务 services.AddBootstrapBlazorTableExportService(); + // 增加离线 IP 定位服务 + services.AddBootstrapBlazorIP2RegionfService(); + // 增加 PetaPoco ORM 数据服务操作类 // 需要时打开下面代码 //services.AddPetaPoco(option => From eb4408e59ec2fe3e390c8b1af5581d573e2463c0 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 10:35:50 +0800 Subject: [PATCH 08/20] =?UTF-8?q?chore:=20=E5=A2=9E=E5=8A=A0=20IP2Region?= =?UTF-8?q?=20=E5=8C=85=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj index 992c3ce45b3..9e9a9b32164 100644 --- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj +++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj @@ -1,4 +1,4 @@ - + true @@ -31,7 +31,7 @@ - + @@ -41,6 +41,7 @@ + From 8b8118790a649bc7313116566f3bb1b818b6efbb Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 11:53:10 +0800 Subject: [PATCH 09/20] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Locales/en-US.json | 2 +- src/BootstrapBlazor.Server/Locales/zh-CN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index f1137fb0d1f..fae7a9e2562 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -4142,7 +4142,7 @@ "LocatorsNormalInputText": "IpAddress", "LocatorsNormalDisplayText": "Geographical location", "LocatorsNormalButtonText": "Locating", - "LocatorsProviderDesc": "The component library has two built-in geolocation locators: BaiduIpLocatorProvider BaiduIpLocatorProviderV2" + "LocatorsProviderDesc": "

The component library has two built-in free online geolocation locators, BaiduIpLocatorProvider BaiduIpLocatorProviderV2

The component library has a built-in paid online geolocation locator JuHeIpLocatorProvider Official website address

The component library has a built-in free offline geolocation locator BootstrapBlazor.IP2Region Nuget package

" }, "BootstrapBlazor.Server.Components.Samples.Print": { "PrintsTitle": "Print", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index 30780cc1212..dbbb087a331 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -4142,7 +4142,7 @@ "LocatorsNormalInputText": "Ip 地址", "LocatorsNormalDisplayText": "地理位置", "LocatorsNormalButtonText": "定位", - "LocatorsProviderDesc": "组件库内置两个地理位置定位器分别为 BaiduIpLocatorProvider BaiduIpLocatorProviderV2" + "LocatorsProviderDesc": "

组件库内置两个免费在线地理位置定位器分别为 BaiduIpLocatorProvider BaiduIpLocatorProviderV2

组件库内置一个收费在线地理位置定位器 JuHeIpLocatorProvider 官网地址

组件库内置一个免费离线地理位置定位器 BootstrapBlazor.IP2Region Nuget 包

" }, "BootstrapBlazor.Server.Components.Samples.Print": { "PrintsTitle": "Print 打印按钮", From 467284d22a7996d85d742f0596d768c720ef35bc Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 11:57:51 +0800 Subject: [PATCH 10/20] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=20JuHeIpLo?= =?UTF-8?q?catorOptions=20=E9=85=8D=E7=BD=AE=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IPLocator/JuHeIpLocatorOptions.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorOptions.cs diff --git a/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorOptions.cs b/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorOptions.cs new file mode 100644 index 00000000000..ce58ec2c29c --- /dev/null +++ b/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorOptions.cs @@ -0,0 +1,27 @@ +// 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 + +namespace BootstrapBlazor.Components; + +/// +/// 聚合搜索引擎 IP 定位器配置类 +/// +class JuHeIpLocatorOptions +{ + /// + /// 聚合搜索引擎 IP 定位器 AppKey + /// + public string Key { get; set; } = ""; + + /// + /// 聚合搜索引擎 IP 定位器请求地址 + /// + public string Url { get; set; } = "http://apis.juhe.cn/ip/ipNew"; + + /// + /// 聚合搜索引擎 IP 定位器请求超时时间 默认 5 秒 + /// + public TimeSpan Timeout { get; set; } +} From 1d5c11a70f0c954499aa7e79ff55732083765170 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 11:58:02 +0800 Subject: [PATCH 11/20] =?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 --- .../IPLocator/JuHeIpLocatorProvider.cs | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorProvider.cs b/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorProvider.cs index 7a6dcab3943..bb562758aca 100644 --- a/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorProvider.cs +++ b/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorProvider.cs @@ -21,7 +21,7 @@ public class JuHeIpLocatorProvider(IHttpClientFactory httpClientFactory, IConfig { private HttpClient? _client; - private string? _key; + private JuHeIpLocatorOptions? _options; /// /// @@ -30,13 +30,12 @@ public class JuHeIpLocatorProvider(IHttpClientFactory httpClientFactory, IConfig protected override async Task LocateByIp(string ip) { string? ret = null; - _key ??= GetKey(); - var url = $"https://apis.juhe.cn/iplocation/ipv4dist/query?ip={ip}&key={_key}"; + _options ??= GetOptions(); + var url = $"{_options.Url}?ip={ip}&key={_options.Key}"; try { _client ??= httpClientFactory.CreateClient(); - using var token = new CancellationTokenSource(3000); - ret = await Fetch(url, _client, token.Token); + ret = await Fetch(url, _client); } catch (Exception ex) { @@ -45,14 +44,27 @@ public class JuHeIpLocatorProvider(IHttpClientFactory httpClientFactory, IConfig return ret; } - private string GetKey() + private JuHeIpLocatorOptions GetOptions() { - var ret = configuration["JuHe:IpLocatorKey"]; - if (string.IsNullOrEmpty(ret)) + var options = new JuHeIpLocatorOptions(); + + try + { + configuration.Bind(nameof(JuHeIpLocatorOptions), options); + if (string.IsNullOrEmpty(options.Key)) + { + throw new InvalidOperationException($"{nameof(JuHeIpLocatorOptions)}:Key not value in appsettings configuration file. 未配置 {nameof(JuHeIpLocatorOptions)}:Key 请在 appsettings.json 中配置 {nameof(JuHeIpLocatorOptions)}:Key"); + } + if (string.IsNullOrEmpty(options.Url)) + { + options.Url = "http://apis.juhe.cn/ip/ipNewV3"; + } + } + catch (Exception ex) { - throw new InvalidOperationException("JuHe:IpLocatorKey not value in appsettings configuration file. 未配置 JuHe:IpLocatorKey 请在 appsettings.json 中配置 JuHe:IpLocatorKey"); + logger.LogError(ex, "{GetOptions} failed", nameof(GetOptions)); } - return ret; + return options; } /// @@ -60,11 +72,11 @@ private string GetKey() /// /// /// - /// /// - protected virtual async Task Fetch(string url, HttpClient client, CancellationToken token) + private async Task Fetch(string url, HttpClient client) { - var result = await client.GetFromJsonAsync(url, token); + using var token = new CancellationTokenSource(_options?.Timeout ?? TimeSpan.FromSeconds(3)); + var result = await client.GetFromJsonAsync(url, token.Token); if (result != null && result.ErrorCode != 0) { logger.LogError("ErrorCode: {ErrorCode} Reason: {Reason}", result.ErrorCode, result.Reason); From 01a941d29fd035740d47f35a878def9ad7a051a2 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 12:59:15 +0800 Subject: [PATCH 12/20] =?UTF-8?q?chore:=20=E7=A7=BB=E9=99=A4=20JuHeIpLocat?= =?UTF-8?q?orProvider?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IPLocator/JuHeIpLocatorOptions.cs | 27 --- .../IPLocator/JuHeIpLocatorProvider.cs | 215 ------------------ 2 files changed, 242 deletions(-) delete mode 100644 src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorOptions.cs delete mode 100644 src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorProvider.cs diff --git a/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorOptions.cs b/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorOptions.cs deleted file mode 100644 index ce58ec2c29c..00000000000 --- a/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorOptions.cs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 - -namespace BootstrapBlazor.Components; - -/// -/// 聚合搜索引擎 IP 定位器配置类 -/// -class JuHeIpLocatorOptions -{ - /// - /// 聚合搜索引擎 IP 定位器 AppKey - /// - public string Key { get; set; } = ""; - - /// - /// 聚合搜索引擎 IP 定位器请求地址 - /// - public string Url { get; set; } = "http://apis.juhe.cn/ip/ipNew"; - - /// - /// 聚合搜索引擎 IP 定位器请求超时时间 默认 5 秒 - /// - public TimeSpan Timeout { get; set; } -} diff --git a/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorProvider.cs b/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorProvider.cs deleted file mode 100644 index bb562758aca..00000000000 --- a/src/BootstrapBlazor/Services/IPLocator/JuHeIpLocatorProvider.cs +++ /dev/null @@ -1,215 +0,0 @@ -// 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 Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using System.Net.Http.Json; -using System.Text.Json.Serialization; - -namespace BootstrapBlazor.Components; - -/// -/// 聚合搜索引擎 IP 定位器 -/// -/// -/// -/// -/// -public class JuHeIpLocatorProvider(IHttpClientFactory httpClientFactory, IConfiguration configuration, IOptions options, ILogger logger) : DefaultIpLocatorProvider(options) -{ - private HttpClient? _client; - - private JuHeIpLocatorOptions? _options; - - /// - /// - /// - /// - protected override async Task LocateByIp(string ip) - { - string? ret = null; - _options ??= GetOptions(); - var url = $"{_options.Url}?ip={ip}&key={_options.Key}"; - try - { - _client ??= httpClientFactory.CreateClient(); - ret = await Fetch(url, _client); - } - catch (Exception ex) - { - logger.LogError(ex, "Url: {url}", url); - } - return ret; - } - - private JuHeIpLocatorOptions GetOptions() - { - var options = new JuHeIpLocatorOptions(); - - try - { - configuration.Bind(nameof(JuHeIpLocatorOptions), options); - if (string.IsNullOrEmpty(options.Key)) - { - throw new InvalidOperationException($"{nameof(JuHeIpLocatorOptions)}:Key not value in appsettings configuration file. 未配置 {nameof(JuHeIpLocatorOptions)}:Key 请在 appsettings.json 中配置 {nameof(JuHeIpLocatorOptions)}:Key"); - } - if (string.IsNullOrEmpty(options.Url)) - { - options.Url = "http://apis.juhe.cn/ip/ipNewV3"; - } - } - catch (Exception ex) - { - logger.LogError(ex, "{GetOptions} failed", nameof(GetOptions)); - } - return options; - } - - /// - /// 请求获得地理位置接口方法 - /// - /// - /// - /// - private async Task Fetch(string url, HttpClient client) - { - using var token = new CancellationTokenSource(_options?.Timeout ?? TimeSpan.FromSeconds(3)); - var result = await client.GetFromJsonAsync(url, token.Token); - if (result != null && result.ErrorCode != 0) - { - logger.LogError("ErrorCode: {ErrorCode} Reason: {Reason}", result.ErrorCode, result.Reason); - } - return result?.ToString(); - } - - /// - /// LocationResult 结构体 - /// - [ExcludeFromCodeCoverage] - class LocationResult - { - /// - /// 获得/设置 结果状态返回码 为 查询成功 时通讯正常 - /// - public string? Reason { get; set; } - - /// - /// 获得/设置 错误码 - /// - [JsonPropertyName("error_code")] - public int ErrorCode { get; set; } - - /// - /// 获得/设置 定位信息 - /// - public LocationData? Result { get; set; } - - /// - /// - /// - /// - public override string? ToString() - { - string? ret = null; - if (ErrorCode == 0) - { - ret = Result?.Country == "中国" - ? $"{Result?.Prov}{Result?.City}{Result?.District} {Result?.Isp}" - : $"{Result?.Continent} {Result?.Country} {Result?.City}"; - } - return ret; - } - } - - - [ExcludeFromCodeCoverage] - class LocationData - { - /// - /// 获得/设置 州 - /// - public string? Continent { get; set; } - - /// - /// 获得/设置 国家 - /// - public string? Country { get; set; } - - /// - /// 获得/设置 邮编 - /// - public string? ZipCode { get; set; } - - /// - /// 获得/设置 时区 - /// - public string? TimeZone { get; set; } - - /// - /// 获得/设置 精度 - /// - public string? Accuracy { get; set; } - - /// - /// 获得/设置 所属 - /// - public string? Owner { get; set; } - - /// - /// 获得/设置 运营商 - /// - public string? Isp { get; set; } - - /// - /// 获得/设置 来源 - /// - public string? Source { get; set; } - - /// - /// 获得/设置 区号 - /// - public string? AreaCode { get; set; } - - /// - /// 获得/设置 行政区划代码 - /// - public string? AdCode { get; set; } - - /// - /// 获得/设置 国家代码 - /// - public string? AsNumber { get; set; } - - /// - /// 获得/设置 经度 - /// - public string? Lat { get; set; } - - /// - /// 获得/设置 纬度 - /// - public string? Lng { get; set; } - - /// - /// 获得/设置 半径 - /// - public string? Radius { get; set; } - - /// - /// 获得/设置 省份 - /// - public string? Prov { get; set; } - - /// - /// 获得/设置 城市 - /// - public string? City { get; set; } - - /// - /// 获得/设置 区县 - /// - public string? District { get; set; } - } -} From 4ed66ab8464f811e7ba8d7549440fa6f3c22a220 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 12:59:24 +0800 Subject: [PATCH 13/20] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Services/IpLocatorTest.cs | 93 ------------------------- 1 file changed, 93 deletions(-) diff --git a/test/UnitTest/Services/IpLocatorTest.cs b/test/UnitTest/Services/IpLocatorTest.cs index c4aab8cdc5d..cec2e66c512 100644 --- a/test/UnitTest/Services/IpLocatorTest.cs +++ b/test/UnitTest/Services/IpLocatorTest.cs @@ -61,26 +61,6 @@ public async Task BaiduIpLocatorProviderV2_Ok() Assert.Equal("省份城市区县 测试", result); } - [Fact] - public async Task JuHeIpLocatorProvider_Ok() - { - var factory = Context.Services.GetRequiredService(); - var option = Context.Services.GetRequiredService>(); - var logger = Context.Services.GetRequiredService>(); - var configuration = Context.Services.GetRequiredService(); - var provider = new MockJuHeProvider(factory, configuration, option, logger); - - var result = await provider.Locate("127.0.0.1"); - Assert.Equal("localhost", result); - - result = await provider.Locate(""); - Assert.Equal("localhost", result); - - // 河南省漯河市 移动 - result = await provider.Locate("223.91.188.112"); - Assert.Equal("省份城市区县 测试", result); - } - [Fact] public void Factory_Ok() { @@ -111,12 +91,6 @@ public async Task Fetch_Error() var cancelPprovider = new MockProviderFetchCancelError(factory, option, logger); result = await cancelPprovider.Locate("223.91.188.112"); Assert.Null(result); - - var configuration = Context.Services.GetRequiredService(); - var juHeLogger = Context.Services.GetRequiredService>(); - var juHeProvider = new MockProviderJuHeFetchError(factory, configuration, option, juHeLogger); - result = await juHeProvider.Locate("223.91.188.112"); - Assert.Null(result); } [Fact] @@ -134,32 +108,6 @@ public async Task Fetch_Result_Fail() var providerV2 = new MockBaiduProviderV2(factory, option, loggerV2); result = await providerV2.Locate("223.91.188.112"); Assert.Null(result); - - var configuration = Context.Services.GetRequiredService(); - var loggerJuHe = Context.Services.GetRequiredService>(); - var providerJuHe = new MockJuHeNullProvider(factory, configuration, option, loggerJuHe); - result = await providerJuHe.Locate("223.91.188.112"); - Assert.Null(result); - - var providerJuHeFailed = new MockJuHeFailProvider(factory, configuration, option, loggerJuHe); - result = await providerJuHeFailed.Locate("223.91.188.112"); - Assert.Null(result); - } - - [Fact] - public async Task JuHe_Section_Error() - { - var factory = Context.Services.GetRequiredService(); - var option = Context.Services.GetRequiredService>(); - var logger = Context.Services.GetRequiredService>(); - var builder = new ConfigurationBuilder(); - builder.AddInMemoryCollection(new Dictionary - { - ["JuHe:IpLocatorKey"] = "" - }); - var configuration = builder.Build(); - var provider = new MockJuHeNullProvider(factory, configuration, option, logger); - await Assert.ThrowsAsync(async () => await provider.Locate("223.91.188.112")); } class MockProviderFetchError(IHttpClientFactory httpClientFactory, IOptions option, ILogger logger) : BaiduIpLocatorProvider(httpClientFactory, option, logger) @@ -172,11 +120,6 @@ class MockProviderFetchCancelError(IHttpClientFactory httpClientFactory, IOption protected override Task Fetch(string url, HttpClient client, CancellationToken token) => throw new TaskCanceledException(); } - class MockProviderJuHeFetchError(IHttpClientFactory httpClientFactory, IConfiguration configuration, IOptions option, ILogger logger) : JuHeIpLocatorProvider(httpClientFactory, configuration, option, logger) - { - protected override Task Fetch(string url, HttpClient client, CancellationToken token) => throw new InvalidOperationException(); - } - class MockBaiduProvider(IHttpClientFactory httpClientFactory, IOptions option, ILogger logger) : BaiduIpLocatorProvider(httpClientFactory, option, logger) { protected override Task Fetch(string url, HttpClient client, CancellationToken token) @@ -195,24 +138,6 @@ class MockBaiduProviderV2(IHttpClientFactory httpClientFactory, IOptions option, ILogger logger) : JuHeIpLocatorProvider(httpClientFactory, configuration, option, logger) - { - protected override Task Fetch(string url, HttpClient client, CancellationToken token) - { - client = new HttpClient(new MockHttpNullMessageHandler(), true); - return base.Fetch(url, client, token); - } - } - - class MockJuHeFailProvider(IHttpClientFactory httpClientFactory, IConfiguration configuration, IOptions option, ILogger logger) : JuHeIpLocatorProvider(httpClientFactory, configuration, option, logger) - { - protected override Task Fetch(string url, HttpClient client, CancellationToken token) - { - client = new HttpClient(new MockHttpFailedMessageHandlerJuHe(), true); - return base.Fetch(url, client, token); - } - } - class MockProvider(IHttpClientFactory httpClientFactory, IOptions option, ILogger logger) : BaiduIpLocatorProvider(httpClientFactory, option, logger) { protected override Task Fetch(string url, HttpClient client, CancellationToken token) @@ -231,24 +156,6 @@ class MockProviderV2(IHttpClientFactory httpClientFactory, IOptions option, ILogger logger) : JuHeIpLocatorProvider(httpClientFactory, configuration, option, logger) - { - protected override Task Fetch(string url, HttpClient client, CancellationToken token) - { - client = new HttpClient(new MockHttpSuccessMessageHandlerJuHe(), true); - return base.Fetch(url, client, token); - } - } - - class MockJuHeFailedProvider(IHttpClientFactory httpClientFactory, IConfiguration configuration, IOptions option, ILogger logger) : JuHeIpLocatorProvider(httpClientFactory, configuration, option, logger) - { - protected override Task Fetch(string url, HttpClient client, CancellationToken token) - { - client = new HttpClient(new MockHttpFailedMessageHandlerJuHe(), true); - return base.Fetch(url, client, token); - } - } - class MockHttpNullMessageHandler : HttpMessageHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) From a16e0c1028330a5e80c4678c51c933d1988451e8 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 12:59:41 +0800 Subject: [PATCH 14/20] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=E6=B3=A8?= =?UTF-8?q?=E5=85=A5=E6=9C=8D=E5=8A=A1=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/BootstrapBlazorServiceCollectionExtensions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/BootstrapBlazor/Extensions/BootstrapBlazorServiceCollectionExtensions.cs b/src/BootstrapBlazor/Extensions/BootstrapBlazorServiceCollectionExtensions.cs index 163f66f6756..8c4f8d903a4 100644 --- a/src/BootstrapBlazor/Extensions/BootstrapBlazorServiceCollectionExtensions.cs +++ b/src/BootstrapBlazor/Extensions/BootstrapBlazorServiceCollectionExtensions.cs @@ -47,7 +47,6 @@ public static IServiceCollection AddBootstrapBlazor(this IServiceCollection serv // IP 地理位置定位服务 services.TryAddSingleton(); - services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); From e02a3483405ebef3a79ba4ce331de4e9389a039e Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 12:59:51 +0800 Subject: [PATCH 15/20] chore: bump version 9.3.1-beta24 --- src/BootstrapBlazor/BootstrapBlazor.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 86ee6197a7c..6cb35269ddc 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@ - 9.3.1-beta23 + 9.3.1-beta24 From 2c8138c38847bf1afb43f41622c575819490f9cb Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 13:00:10 +0800 Subject: [PATCH 16/20] =?UTF-8?q?chore:=20=E5=A2=9E=E5=8A=A0=20BootstrapBl?= =?UTF-8?q?azor.JuHeIpLocatorProvider=20=E5=8C=85=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj | 1 + .../Extensions/ServiceCollectionSharedExtensions.cs | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj index 9e9a9b32164..4f7700e9aba 100644 --- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj +++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj @@ -42,6 +42,7 @@ + diff --git a/src/BootstrapBlazor.Server/Extensions/ServiceCollectionSharedExtensions.cs b/src/BootstrapBlazor.Server/Extensions/ServiceCollectionSharedExtensions.cs index 479c7981f93..d34dd4a48df 100644 --- a/src/BootstrapBlazor.Server/Extensions/ServiceCollectionSharedExtensions.cs +++ b/src/BootstrapBlazor.Server/Extensions/ServiceCollectionSharedExtensions.cs @@ -82,6 +82,9 @@ public static IServiceCollection AddBootstrapBlazorServices(this IServiceCollect // 增加离线 IP 定位服务 services.AddBootstrapBlazorIP2RegionfService(); + // 增加 JuHe 定位服务 + services.AddBootstrapBlazorJuHeIpLocatorService(); + // 增加 PetaPoco ORM 数据服务操作类 // 需要时打开下面代码 //services.AddPetaPoco(option => From 5e05e1694ad9a6e5d1ffdf383a09ec7b07ba5b7c Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 13:06:02 +0800 Subject: [PATCH 17/20] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Locales/en-US.json | 2 +- src/BootstrapBlazor.Server/Locales/zh-CN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index fae7a9e2562..e1dae3769ac 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -4142,7 +4142,7 @@ "LocatorsNormalInputText": "IpAddress", "LocatorsNormalDisplayText": "Geographical location", "LocatorsNormalButtonText": "Locating", - "LocatorsProviderDesc": "

The component library has two built-in free online geolocation locators, BaiduIpLocatorProvider BaiduIpLocatorProviderV2

The component library has a built-in paid online geolocation locator JuHeIpLocatorProvider Official website address

The component library has a built-in free offline geolocation locator BootstrapBlazor.IP2Region Nuget package

" + "LocatorsProviderDesc": "

The component library has two built-in free online geolocation locators, BaiduIpLocatorProvider BaiduIpLocatorProviderV2

The component library has a built-in paid online geolocation locator BootstrapBlazor.JuHeIpLocatorProvider Nuget package Official website address

The component library has a built-in free offline geolocation locator BootstrapBlazor.IP2Region Nuget package

" }, "BootstrapBlazor.Server.Components.Samples.Print": { "PrintsTitle": "Print", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index dbbb087a331..1a56417b3b0 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -4142,7 +4142,7 @@ "LocatorsNormalInputText": "Ip 地址", "LocatorsNormalDisplayText": "地理位置", "LocatorsNormalButtonText": "定位", - "LocatorsProviderDesc": "

组件库内置两个免费在线地理位置定位器分别为 BaiduIpLocatorProvider BaiduIpLocatorProviderV2

组件库内置一个收费在线地理位置定位器 JuHeIpLocatorProvider 官网地址

组件库内置一个免费离线地理位置定位器 BootstrapBlazor.IP2Region Nuget 包

" + "LocatorsProviderDesc": "

组件库内置两个免费在线地理位置定位器分别为 BaiduIpLocatorProvider BaiduIpLocatorProviderV2

组件库内置一个收费在线地理位置定位器 BootstrapBlazor.JuHeIpLocatorProvider Nuget 包 官网地址

组件库内置一个免费离线地理位置定位器 BootstrapBlazor.IP2Region Nuget 包

" }, "BootstrapBlazor.Server.Components.Samples.Print": { "PrintsTitle": "Print 打印按钮", From a24242ae0f7d7d1ee37b25f84dd3fcea45d25329 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 13:06:40 +0800 Subject: [PATCH 18/20] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Services/IpLocatorTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/UnitTest/Services/IpLocatorTest.cs b/test/UnitTest/Services/IpLocatorTest.cs index cec2e66c512..b22b30d5514 100644 --- a/test/UnitTest/Services/IpLocatorTest.cs +++ b/test/UnitTest/Services/IpLocatorTest.cs @@ -67,7 +67,6 @@ public void Factory_Ok() var factory = Context.Services.GetRequiredService(); Assert.NotNull(factory.Create("BaiduIpLocatorProviderV2")); Assert.NotNull(factory.Create("BaiduIpLocatorProvider")); - Assert.NotNull(factory.Create("JuHeIpLocatorProvider")); Assert.NotNull(factory.Create()); } From cc0a25a54bb32afddab30fd8f2cf0915592eff66 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 13:08:42 +0800 Subject: [PATCH 19/20] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20Keyed=20?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/BootstrapBlazorServiceCollectionExtensions.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/BootstrapBlazor/Extensions/BootstrapBlazorServiceCollectionExtensions.cs b/src/BootstrapBlazor/Extensions/BootstrapBlazorServiceCollectionExtensions.cs index 8c4f8d903a4..12af4f4ac80 100644 --- a/src/BootstrapBlazor/Extensions/BootstrapBlazorServiceCollectionExtensions.cs +++ b/src/BootstrapBlazor/Extensions/BootstrapBlazorServiceCollectionExtensions.cs @@ -50,6 +50,11 @@ public static IServiceCollection AddBootstrapBlazor(this IServiceCollection serv services.AddSingleton(); services.AddSingleton(); +#if NET8_0_OR_GREATER + services.AddKeyedSingleton(nameof(BaiduIpLocatorProvider)); + services.AddKeyedSingleton(nameof(BaiduIpLocatorProviderV2)); +#endif + // 节日服务 services.TryAddSingleton(); From 804f6d5eb15398752f6a246310bb9bf34f70ba95 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Thu, 20 Feb 2025 13:13:16 +0800 Subject: [PATCH 20/20] =?UTF-8?q?test:=20=E5=A2=9E=E5=8A=A0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Services/IpLocatorTest.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/UnitTest/Services/IpLocatorTest.cs b/test/UnitTest/Services/IpLocatorTest.cs index b22b30d5514..bc3ebd9b04e 100644 --- a/test/UnitTest/Services/IpLocatorTest.cs +++ b/test/UnitTest/Services/IpLocatorTest.cs @@ -68,6 +68,9 @@ public void Factory_Ok() Assert.NotNull(factory.Create("BaiduIpLocatorProviderV2")); Assert.NotNull(factory.Create("BaiduIpLocatorProvider")); Assert.NotNull(factory.Create()); + + Assert.NotNull(Context.Services.GetKeyedService("BaiduIpLocatorProvider")); + Assert.NotNull(Context.Services.GetKeyedService("BaiduIpLocatorProviderV2")); } [Fact]