diff --git a/docs/en/Localization.md b/docs/en/Localization.md
index 089567422c..a432d6afb2 100644
--- a/docs/en/Localization.md
+++ b/docs/en/Localization.md
@@ -87,6 +87,8 @@ A JSON localization file content is shown below:
* Every localization file should define the `culture` code for the file (like "en" or "en-US").
* `texts` section just contains key-value collection of the localization strings (keys may have spaces too).
+> ABP will ignore (skip) the JSON file if the `culture` section is missing.
+
### Default Resource
`AbpLocalizationOptions.DefaultResourceType` can be set to a resource type, so it is used when the localization resource was not specified:
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs
index abbfb9b9c6..04ec79aaf6 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Json/JsonLocalizationDictionaryBuilder.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
+using JetBrains.Annotations;
using Microsoft.Extensions.Localization;
namespace Volo.Abp.Localization.Json;
@@ -12,6 +13,7 @@ public static class JsonLocalizationDictionaryBuilder
/// Builds an from given file.
///
/// Path of the file
+ [CanBeNull]
public static ILocalizationDictionary BuildFromFile(string filePath)
{
try
@@ -36,6 +38,7 @@ public static class JsonLocalizationDictionaryBuilder
/// Builds an from given json string.
///
/// Json string
+ [CanBeNull]
public static ILocalizationDictionary BuildFromJsonString(string jsonString)
{
JsonLocalizationFile jsonFile;
@@ -47,11 +50,11 @@ public static class JsonLocalizationDictionaryBuilder
{
throw new AbpException("Can not parse json string. " + ex.Message);
}
-
+
var cultureCode = jsonFile.Culture;
if (string.IsNullOrEmpty(cultureCode))
{
- throw new AbpException("Culture is empty in language json file.");
+ return null;
}
var dictionary = new Dictionary();
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs
index 1713adc473..40bb9de7c5 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/VirtualFiles/VirtualFileLocalizationResourceContributorBase.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
+using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Localization;
@@ -98,6 +99,12 @@ public abstract class VirtualFileLocalizationResourceContributorBase : ILocaliza
}
var dictionary = CreateDictionaryFromFile(file);
+
+ if (dictionary == null)
+ {
+ continue;
+ }
+
if (dictionaries.ContainsKey(dictionary.CultureName))
{
throw new AbpException($"{file.GetVirtualOrPhysicalPathOrNull()} dictionary has a culture name '{dictionary.CultureName}' which is already defined! Localization resource: {_resource.ResourceName}");
@@ -111,6 +118,7 @@ public abstract class VirtualFileLocalizationResourceContributorBase : ILocaliza
protected abstract bool CanParseFile(IFileInfo file);
+ [CanBeNull]
protected virtual ILocalizationDictionary CreateDictionaryFromFile(IFileInfo file)
{
using (var stream = file.CreateReadStream())
@@ -119,5 +127,6 @@ public abstract class VirtualFileLocalizationResourceContributorBase : ILocaliza
}
}
+ [CanBeNull]
protected abstract ILocalizationDictionary CreateDictionaryFromFileContent(string fileContent);
}