diff --git a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs index 765f3f7717..88eb8a399d 100644 --- a/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs +++ b/framework/src/Volo.Abp.Localization.Abstractions/Volo/Abp/Localization/LocalizableString.cs @@ -12,7 +12,7 @@ public class LocalizableString : ILocalizableString [NotNull] public string Name { get; } - public LocalizableString(Type resourceType, [NotNull] string name) + public LocalizableString([CanBeNull] Type resourceType, [NotNull] string name) { Name = Check.NotNullOrEmpty(name, nameof(name)); ResourceType = resourceType; diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizableStringSerializer.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizableStringSerializer.cs new file mode 100644 index 0000000000..6f7a487b6c --- /dev/null +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILocalizableStringSerializer.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.Localization; + +public interface ILocalizableStringSerializer +{ + string Serialize(ILocalizableString localizableString); + + ILocalizableString Deserialize(string value); +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizableStringSerializer.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizableStringSerializer.cs new file mode 100644 index 0000000000..b9cd6528fe --- /dev/null +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizableStringSerializer.cs @@ -0,0 +1,64 @@ +using System; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Localization; + +public class LocalizableStringSerializer : ILocalizableStringSerializer, ITransientDependency +{ + protected AbpLocalizationOptions LocalizationOptions { get; } + + public LocalizableStringSerializer(IOptions localizationOptions) + { + LocalizationOptions = localizationOptions.Value; + } + + public virtual string Serialize(ILocalizableString localizableString) + { + if (localizableString is LocalizableString realLocalizableString) + { + return $"L:{LocalizationResourceNameAttribute.GetName(realLocalizableString.ResourceType)},{realLocalizableString.Name}"; + } + + if (localizableString is FixedLocalizableString fixedLocalizableString) + { + return $"F:{fixedLocalizableString.Value}"; + } + + throw new AbpException($"Unknown {nameof(ILocalizableString)} type: {localizableString.GetType().FullName}"); + } + + public virtual ILocalizableString Deserialize(string value) + { + if (value.IsNullOrEmpty() || + value.Length < 3 || + value[1] != ':') + { + return new FixedLocalizableString(value); + } + + var type = value[0]; + switch (type) + { + case 'F': + return new FixedLocalizableString(value.Substring(2)); + case 'L': + var commaPosition = value.IndexOf(',', 2); + if (commaPosition == -1) + { + throw new AbpException("Invalid LocalizableString value: " + value); + } + + var resourceName = value.Substring(2, commaPosition - 2); + var name = value.Substring(commaPosition + 1); + var resourceType = LocalizationOptions.Resources.GetOrNull(resourceName)?.ResourceType; + + return new LocalizableString( + resourceType, + name + ); + default: + return new FixedLocalizableString(value); + } + } +} \ No newline at end of file