Skip to content

Commit 5960d5c

Browse files
fix(CacheManager): GetJsonStringByTypeName prevent throw ArgumentNull exception (#5106)
* fix CacheManager GetLocalizedString Key.Value Null * feat: 增加 UseKeyWhenValueIsNull 参数 * refactor: 优化代码 * refactor: 优化代码 * feat: 增加 UseKeyWhenValueIsNull 逻辑 * test: 增加单元测试 * refactor: 增加 null 保护防止报异常 * test: 更新单元测试 --------- Co-Authored-By: Argo-iMac <[email protected]>
1 parent 85b22b1 commit 5960d5c

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

src/BootstrapBlazor/Localization/Json/JsonLocalizationOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public class JsonLocalizationOptions : LocalizationOptions
4343
/// </summary>
4444
public bool IgnoreLocalizerMissing { get; set; }
4545

46+
/// <summary>
47+
/// 获得/设置 如果 Value 值为 null 时使用 Key 代替 默认 false 触发异常
48+
/// </summary>
49+
public bool UseKeyWhenValueIsNull { get; set; }
50+
4651
/// <summary>
4752
/// 获得/设置 资源文件是否热加载 默认 false
4853
/// </summary>

src/BootstrapBlazor/Services/CacheManager.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,7 @@ public static int ElementCount(object? value)
152152
entry.SetDynamicAssemblyPolicy(type);
153153
return LambdaExtensions.CountLambda(type).Compile();
154154
});
155-
if (invoker != null)
156-
{
157-
ret = invoker(value);
158-
}
155+
ret = invoker(value);
159156
}
160157
return ret;
161158
}
@@ -237,12 +234,20 @@ private static JsonLocalizationOptions GetJsonLocalizationOption()
237234
Instance.Cache.Remove(key);
238235
Instance.Cache.Remove(typeKey);
239236
}
240-
return Instance.GetOrCreate(typeKey, entry =>
237+
return Instance.GetOrCreate(typeKey, _ =>
241238
{
242-
var sections = Instance.GetOrCreate(key, entry => option.GetJsonStringFromAssembly(assembly, cultureName));
239+
var sections = Instance.GetOrCreate(key, _ => option.GetJsonStringFromAssembly(assembly, cultureName));
243240
var items = sections.FirstOrDefault(kv => typeName.Equals(kv.Key, StringComparison.OrdinalIgnoreCase))?
244241
.GetChildren()
245-
.SelectMany(kv => new[] { new LocalizedString(kv.Key, kv.Value!, false, typeName) });
242+
.Select(kv =>
243+
{
244+
var value = kv.Value;
245+
if (value == null && option.UseKeyWhenValueIsNull == true)
246+
{
247+
value = kv.Key;
248+
}
249+
return new LocalizedString(kv.Key, value ?? "", false, typeName);
250+
});
246251
#if NET8_0_OR_GREATER
247252
return items?.ToFrozenSet();
248253
#else

test/UnitTest/Locales/en-US.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,9 @@
2525
"PlaceHolder": "Click to select ...",
2626
"Primary": "Primary",
2727
"Middle": "Middle"
28+
},
29+
"UnitTest.Utils.UtilityTest": {
30+
"Test-Null": null,
31+
"Test-Key:": ""
2832
}
2933
}

test/UnitTest/Utils/UtilityTest.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,34 @@ public void GetJsonStringByTypeName_Ok()
379379
Utility.GetJsonStringByTypeName(option, dynamicType!.Assembly, "Test");
380380
}
381381

382+
[Fact]
383+
public void GetJsonStringByTypeName_UseKeyWhenValueIsNull()
384+
{
385+
// improve code coverage
386+
var option = Context.Services.GetRequiredService<IOptions<JsonLocalizationOptions>>().Value;
387+
option.UseKeyWhenValueIsNull = true;
388+
var items = Utility.GetJsonStringByTypeName(option, this.GetType().Assembly, "UnitTest.Utils.UtilityTest", "en-US", true);
389+
390+
var test1 = items.FirstOrDefault(i => i.Name == "Test-Null");
391+
Assert.NotNull(test1);
392+
Assert.Equal("", test1.Value);
393+
394+
var test2 = items.FirstOrDefault(i => i.Name == "Test-Key");
395+
Assert.NotNull(test2);
396+
Assert.Equal("Test-Key", test2.Value);
397+
398+
option.UseKeyWhenValueIsNull = false;
399+
items = Utility.GetJsonStringByTypeName(option, this.GetType().Assembly, "UnitTest.Utils.UtilityTest", "en-US", true);
400+
401+
test1 = items.FirstOrDefault(i => i.Name == "Test-Null");
402+
Assert.NotNull(test1);
403+
Assert.Equal("", test1.Value);
404+
405+
test2 = items.FirstOrDefault(i => i.Name == "Test-Key");
406+
Assert.NotNull(test2);
407+
Assert.Equal("", test2.Value);
408+
}
409+
382410
private class MockDynamicObject : IDynamicObject
383411
{
384412
public Guid DynamicObjectPrimaryKey { get; set; }

0 commit comments

Comments
 (0)