可以在运行时更新具有 XML 源的 DisplayNameAttribute 扩展吗?

Can DisplayNameAttribute extension with XML source update in runtime?

这可能更多的是与 .NET Framework 的工作原理相关的问题,而不是寻找实际的解决方案。原因是我想知道这是我应该在修复时追求的东西,还是完全尝试其他东西。我做了一些搜索,但找不到我认为正确的答案。

我正在开发一个 ASP.NET MVC5 应用程序,该应用程序使用翻译提供程序并以 XML 文件作为源。在某些情况下,我使用 DisplayNameAttribute 扩展来装饰模型属性以提供翻译。它是通过参考这里的解决方案制作的:

这是我的实现:

[AttributeUsage(AttributeTargets.Property)]
public sealed class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
    public LocalizedDisplayNameAttribute(string key, string page = null) : base(FormatMessage(key, page))
    {
    }

    private static string FormatMessage(string key, string page = null)
    {
        if (!string.IsNullOrWhiteSpace(key) && string.IsNullOrWhiteSpace(page))
        {
            return TextGetter.GetText(key);
        }
        else if (!string.IsNullOrWhiteSpace(key) && !string.IsNullOrWhiteSpace(page))
        {
            return TextGetter.GetText(key, page);
        }
        else
        {
            return string.Empty;
        }
    }
}

“TextGetter”是一个单独的库,用于处理从 XML 数据源中获取字符串。

属性扩展的用法如下:

[LocalizedDisplayName("Timestamp", "/report")]
public DateTimeOffset Timestamp { get; set; }

该网站还有一个功能,超级用户可以编辑翻译 XML 文件,以防某些翻译错误或丢失。通常 XML 文件中的编辑会立即可见,但具有此特定属性的属性除外。我知道通常当使用具有硬编码值的 DisplayName 属性时不能更改,因为它是编译的,尽管我假设因为这使用 XML 文件作为参考,我相信如果 XML 已更改,在这种情况下也会立即反映出来。但这似乎不会发生。

能够即时更改翻译是一项重要功能;我应该寻求其他解决方案吗?我可以在视图中设置带有翻译的 属性 名称,这是可行的,但这将需要大量重构,并将其保留为注释更加简洁。 我真的不知道从哪里拿它。

在此期间找到了一个解决方案,如果有人偶然发现它,就把它放在那里。所以这就是你应该做的,如果你想制作一个派生自 DisplayName 的属性用于本地化,并且最重要的是有一个可以在运行时更改和更新的本地化源:

[AttributeUsage(AttributeTargets.Property)]
public sealed class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
    private readonly string _key;
    private readonly string _page;

    public LocalizedDisplayNameAttribute(string key, string page = null) : base(key)
    {
        this._key = key;
        this._page = page;
    }

    public override string DisplayName => this.FormatMessage(this._key, this._page);

    private string FormatMessage(string key, string page = null)
    {
        if (!string.IsNullOrWhiteSpace(key) && string.IsNullOrWhiteSpace(page))
        {
            return TextGetter.GetText(key);
        }
        else if (!string.IsNullOrWhiteSpace(key) && !string.IsNullOrWhiteSpace(page))
        {
            return TextGetter.GetText(key, page);
        }
        else
        {
            return string.Empty;
        }
    }
}

“FormatMessage”的内容可以是您真正想要的任何内容,只需在其中插入您需要的任何代码以获取翻译后的字符串。