6

I have the requirement that the end-user can change localized resources and the changes should be visible in the application without the need to restart the application.

Update to clarify the scenario:
I am talking about changing the localized resources at runtime. Lets say I have a typo in the german translation of a page. Then some admin-user should have the possibility to change that typo at runtime. There should be no need for a redeployment or restart in order for this change to be reflected in the UI.

I am using ASP.NET MVC3.

What options do I have?

I have been looking into writing a custom ResourceProvider that loads resources from the database.
This seems not too much effort, however so far I pointed out two drawbacks:

  • It is not working with the DataAnnotations that are used for convenient validation in MVC3 (DataAnnotations work with a ErrorMessageResourceType parameter, which only works with compiled resources)
  • We basically have to provide our own tooling around managing resources (like translating etc.) which is a pity, since there are a lot of tools for this that work with resx-files.

What are the other options? Would manipulation of the deployed resx-files at runtime be an option?
But I suspect that the application is automatically "restarted" when it detects those changes: I suspect ASP.NET realizes that the resx-files have changed, it then recycles the application-pool and compiles the new resx-files on the fly.
Is this correct? Is there any way around this?

I have not yet looked into compiling the resources into satellite assemblies before deployment. Is this even a recommended scenario for web applications?
But even with compiled satellite assemblies I suspect that ASP.NET restarts the application, when those assemblies are changed on the fly. Is this correct?

I would be interested in any experience in how the original requirement can be satisfied? And I would be interested in any comments about the options I have mentioned above.

jbandi
  • 17,499
  • 9
  • 69
  • 81
  • 1
    Have you tried the UpdatableResXResourceProvider proposed in [this answer](http://stackoverflow.com/questions/1535027/app-domain-restarts-when-resx-file-changes-any-way-to-avoid-this/1853530#1853530)? – Daniel Liuzzi Aug 27 '11 at 11:35
  • 1
    Sorry I miss-understood, to change existing resources at runtime I think your only option is a custom resource provider, but I haven't seen any clean solutions to solve the DataAnnotations issue without resorting to custom annotations. – TheCodeKing Aug 27 '11 at 11:39
  • I have a way of doing this, but only if your resource keys are fixed? – TheCodeKing Sep 01 '11 at 08:51

1 Answers1

1

DataAnnotations accept a ErrorMessageResourceType which tells the ValidationAttrributes where to access resources. You can pass this as follows:

[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 other implementation. You could then combine this with a dynamic object for DRY and move the implementation into TryGetMember. Potentially then use T4 templates to generate the statics from your database at compile time, ending up with this:

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 perfect if resources weren't static properties.

TheCodeKing
  • 19,064
  • 3
  • 47
  • 70
  • This solution does not work with the custom resource provider approach from MSDN that is linked in the question. The annotation expects the ErrorMessageResourceType to have a static property with the ErrorMessageResourceName. This is not the case when you implement a dynamic resource lookup. – jbandi Sep 01 '11 at 07:12
  • OK there's an alternative, relies on fixed resource keys but then to use resources in your app they need to be predefined anyway. – TheCodeKing Sep 01 '11 at 09:13
  • Thanks! That is probably the best I can get. Still, I will look into other validation strategies before I go with that solution ... – jbandi Sep 04 '11 at 14:37