Home > Mobile >  Can DisplayNameAttribute extension with XML source update in runtime?
Can DisplayNameAttribute extension with XML source update in runtime?

Time:10-27

This might be more of a question related to how .NET Framework works, than looking for an actual solution. Reason is I would like to know if this is something I should pursue in fixing, or try something else entirely. I did some searching, but couldn't find the right answer in my opinion.

I am working on an ASP.NET MVC5 application that utilizes a translation provider with an XML file as it source. In some scenarios I use a DisplayNameAttribute extension to decorate model properties to provide translations. It is made by referencing the solution here: https://stackoverflow.com/a/9723620/1501132

This is my implementation:

[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;
        }
    }
}

The "TextGetter" is a separate library that handles fetching strings from the XML data source.

The attribute extension is used like so:

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

The website also has a feature where a super user can edit the translation XML file, in case some translations are wrong or missing. Usually an edit in the XML file is visible immediately, except for properties with this particular attribute. I know that normally when using DisplayName attribute with a hardcoded value can not be changed because it is compiled, though I was under the assumption that since this uses an XML file as reference, I believed that if the XML was changed it would be reflected immediately in this case as well. But that seems not to happen.

Being able to change translations on the fly is an important feature; should I seek some other solution? I can set the property names with translations in the views, which is working, but that will entail a LOT of refactoring, and keeping it as annotations is just more neat. I don't really know where to take it from here.

CodePudding user response:

Found a solution in the meantime, and just putting it out there if anyone stumbles across it. So this is what you should do, if you want to make an attribute that derives from DisplayName used for localization, and on top of that have a localization source that can change and update during runtime:

[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;
        }
    }
}

The contents of "FormatMessage" can be whatever you want really, just insert there whatever code you need to fetch your translated string.

  • Related