ASP.NET localization: changing resources without restarting the application?

I have a requirement that the end user can modify localized resources, and the changes must be visible in the application without having to restart the application.

Refresh to clarify the scenario:
I am talking about changing localized resources at runtime. Suppose I have a typo in a German translation of a page. Then, some admin users should be able to change this typo at runtime. There should not be a need for redistribution or reloading so that this change is reflected in the user interface.

I am using ASP.NET MVC3.

What options do I have?

I am writing a custom ResourceProvider that loads resources from a database.
This does not seem to be too much effort, but so far I have pointed out two drawbacks:

  • It does not work with DataAnnotations, which are used for convenient verification in MVC3 (DataAnnotations work with the ErrorMessageResourceType parameter, which works only with compiled resources)
  • We mainly need to provide our own tools for managing resources (for example, for translation, etc.), which is very unfortunate, since there are many tools for working with resx files for this.

What are the other options? Will it be possible to manipulate deployed resx files at runtime?
But I suspect that the application automatically "reboots" when it detects these changes: I suspect that ASP.NET understands that the resx files have been modified, then it processes the application pool and compiles new resx files on the fly.
It's right? Is there any way around this?

I have not yet studied compiling resources in satellite assemblies before deployment. Is this even a recommended script for web applications?
But even with assembled satellite assemblies, I suspect that ASP.NET restarts the application when these assemblies change on the fly. Is it correct?

I would be interested to know how to satisfy the initial requirement? And I will be interested in any comments about the options that I mentioned above.

+6
source share
1 answer

DataAnnotations accept an ErrorMessageResourceType , which tells ValidationAttrributes where to access the resources. You can pass it like this:

 [Required( ErrorMessageResourceType = typeof(DynamicResources), ErrorMessageResourceName = "ResourceKey")] public string Username { get; set; } 

By creating a type for this parameter with static properties for each key, you can create an implementation that loads resources from a database or another implementation. Then you can combine this with a dynamic object for DRY and move the implementation to TryGetMember . Potentially then use T4 templates to generate statistics from your database at compile time, resulting in:

 public class DynamicResources : DynamicObject { // move these into partial and generate using T4 public static string MyResource { get { return Singleton.MyResource; } } public static string MyOtherResource { get { return Singleton.MyOtherResource; } } // base implementation to retrieve resources private static dynamic singleton; private static dynamic Singleton { get { return singleton ?? (singleton = new DynamicResources()); } } public override bool TryGetMember(GetMemberBinder binder, out object result) { // some logic here to look up resources result = GetResourceKeyFromDatabase(binder.Name); return true; } } 

Of course, it would be ideal if resources were not static properties.

+1
source

Source: https://habr.com/ru/post/895985/


All Articles