数据库MVC本地化

3

我正在开发一个多语言ASP.NET MVC应用程序(MVC4)。

我希望能够在运行时编辑资源文件字符串而无需重新编译应用程序,也不需要重新启动应用程序池。然而在使用.resx文件时似乎做不到这一点,因此我将字符串资源迁移到了数据库中存储。

我必须从数据库中获取每个标签/字符串资源,这将会导致对于每个请求都需要更多的数据库访问。 如何解决这个问题?

我已经在Google上搜索过,有人建议在登录/注册页面时将资源加载到字典中并将其存储为应用程序变量,然后使用该字典作为资源而不是访问数据库。

我很困惑,什么才是有效的方法。有人能指导我正确的方向,以避免频繁访问数据库吗?

任何帮助/建议将不胜感激。

谢谢

1个回答

0

我在使用.resx文件进行本地化时遇到了同样的问题。当进行翻译的人不是程序员时,它们并不起作用。现在,我们在管理区域中有一个翻译页面。效果非常好。

我们仍然没有一个很好的解决方案来处理数据注释,它们仍然使用.resx文件。我已经削减了下面的源代码,以删除任何对我们实际数据库结构或表的引用。

如果数据库中不存在条目,则回退到使用基础的.resx文件。如果.resx文件中没有条目,则我会在发现大写字母时拆分单词(CamelSpace是一个字符串扩展方法)。

最后,根据您的实现方式,您可能需要删除上下文缓存,尤其是如果您正在缓存在进程外。

以下是一些用法示例:

@LanguageDb.Translate("Enter your first name below","FirstNamePrompt")

@LanguageDb.Me.FirstName

@String
    .Format(LanguageDb
                .Translate(@"You can be insured for 
                      {0} down and {1} payments of {2}"),
            Model.Down,Model.NumPayments,
            Model.InstallmentAmount)



public class LanguageDb : DynamicObject
{
    public static dynamic Me = new LanguageDb();
    private LanguageDb() { }

    public static string Translate(string englishPhrase, string resourceCode = null)
    {
        return GetTranslation(englishPhrase, resourceCode) ?? englishPhrase;
    }
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = GetTranslation(binder.Name);
        return true;
    }

    private static string GetTranslation(string resourceName, string resourceCode = null)
    {
        resourceCode = resourceCode ?? resourceName;
        if (resourceCode.Contains(" ") || resourceCode.Length > 50)
        {
            resourceCode = resourceName.GetHashCode().ToString(CultureInfo.InvariantCulture);
        }
        var lang = (string)HttpContext.Current.Request.RequestContext.RouteData.Values["lang"] ?? "en";

        // cache entries for an hour
        var result = Get(subagent + "_" + lang + "_" + resourceCode, 3600, () =>
        {
            // cache a datacontext object for 30 seconds.
            var context = Get("_context", 30, () => new YourDataContext()) as YourDataContext;
            var translation = context.Translations.FirstOrDefault(row => row.lang == lang && row.Code == resourceCode);
            if (translation == null)
            {
                translation = new Lookup { 
                    Code = resourceCode, 
                    lang = lang, 
                    Value = Language.ResourceManager.GetString(resourceName, Language.Culture) 
                                    ?? resourceName.CamelSpace() 
                };
                context.Translations.Add(translation);
                context.SaveChanges();
            }

            return translation.Value;
        });

        return result;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        // ignore this
        return true;
    }

    public static T Get<T>(string cacheId, int secondsToCache, Func<T> getItemCallback) where T : class
    {
        T item = HttpRuntime.Cache.Get(cacheId) as T;
        if (item == null)
        {
            item = getItemCallback();
            if (secondsToCache > 0)
            {
                HttpRuntime.Cache.Insert(
                    cacheId, item, null, Cache.NoAbsoluteExpiration,
                    new TimeSpan(0, 0, secondsToCache), CacheItemPriority.Normal, null);
            }
            else
            {
                HttpRuntime.Cache.Insert(cacheId, item);
            }
        }
        return item;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接