枚举Asp.net MVC中的可本地化下拉列表

本文关键字:本地化 下拉列表 Asp net MVC 枚举 | 更新日期: 2023-09-27 18:20:32

我有下拉列表,它是从枚举中填充的。我的解决方案项目由两部分组成:域项目和UI项目。这个枚举是域模型的一部分,所以它被放置在域项目中。

public enum ActivityStatus
    {
        InProgress = 0,
        Completed = 1,
        Freezed = 2,
        NotStarted = 3,
        None = 4
    }

我想用RESX文件本地化UI上的下拉内容。我研究了一些解决方案,他们建议在Enum字段上提供自定义属性。但我认为本地化超出了我的领域模型的范围,所以我想在这里拥有这些属性。有没有一种方法可以对我的UI进行本地化?

枚举Asp.net MVC中的可本地化下拉列表

我也在我的项目中本地化了一些枚举,所以,我有一个这样的类,在enums:中创建一个注释

public class LocalizedEnumAttribute : DescriptionAttribute
{
    private PropertyInfo _nameProperty;
    private Type _resourceType;
    public LocalizedEnumAttribute(string displayNameKey)
        : base(displayNameKey)
    {
    }
    public Type NameResourceType
    {
        get
        {
            return _resourceType;
        }
        set
        {
            _resourceType = value;
            _nameProperty = _resourceType.GetProperty(this.Description, BindingFlags.Static | BindingFlags.Public);
        }
    }
    public override string Description
    {
        get
        {
            //check if nameProperty is null and return original display name value
            if (_nameProperty == null)
            {
                return base.Description;
            }
            return (string)_nameProperty.GetValue(_nameProperty.DeclaringType, null);
        }
    }
}

我还有一个EnumHelper类可以在我的项目中使用,以创建本地化的枚举值字典:

public static class EnumHelper
{
    // get description data annotation using RESX files when it has
    public static string GetDescription(Enum @enum)
    {
        if (@enum == null)
            return null;
        string description = @enum.ToString();
        try
        {
            FieldInfo fi = @enum.GetType().GetField(@enum.ToString());
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attributes.Any())
                description = attributes[0].Description;
        }
        catch
        {
        }
        return description;
    }
    public static IDictionary<TKey, string> GetEnumDictionary<T, TKey>()
        where T : struct 
    {
        Type t = typeof (T);
        if (!t.IsEnum)
            throw new InvalidOperationException("The generic type T must be an Enum type.");
        var result = new Dictionary<TKey, string>();
        foreach (Enum r in Enum.GetValues(t))
        {
            var k = Convert.ChangeType(r, typeof(TKey));
            var value = (TKey)k;
            result.Add(value, r.GetDescription());
        }
        return result;
    }
}
public static class EnumExtensions
{
    public static string GetDescription(this Enum @enum)
    {
        return EnumHelper.GetDescription(@enum);
    }
}

有了这个类,你可以在你的枚举中使用:

public enum ActivityStatus 
{ 
    [LocalizedEnum("InProgress", NameResourceType = typeof(Resources.Messages))]
    InProgress = 0, 
    [LocalizedEnum("Completed", NameResourceType = typeof(Resources.Messages))]
    Completed = 1, 
    [LocalizedEnum("Freezed", NameResourceType = typeof(Resources.Messages))]
    Freezed = 2, 
    [LocalizedEnum("NotStarted", NameResourceType = typeof(Resources.Messages))]
    NotStarted = 3, 
    [LocalizedEnum("None", NameResourceType = typeof(Resources.Messages))]
    None = 4 
}

要创建这样的组合框,您可以在asp.net mvc的控制器上使用,类似于以下内容:

var data = EnumHelper.GetEnumDictionary<ActivityStatus, int>();

I guees您可以使用HttpContext.GetGlobalResourceObject()来获取枚举名称的本地化字符串:

// here you get a list of localized strings from `SiteResources.resx` where the keys of strings present by enum names
var names = (Enum.GetNames(typeof(ActivityStatus)).Select(x => HttpContext.GetGlobalResourceObject("SiteResources", x).ToString()).ToList();