Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET


:P
On this page:

I’ve updated my Data Driven Localization Resource Provider for ASP.NET and uploaded a new version of the code and sample project:

http://www.west-wind.com/tools/wwDbResourceProvider/Westwind.Globalization.zip

The resource provider is covered in this article:

http://www.west-wind.com/presentations/wwdbResourceProvider/

that provides an overview of what’s involved in the creation of this custom resource provider and editor that uses a database to hold localized resources. You can find a demo of the provider in action and live editor here (with English and German resources):

http://www.west-wind.com/WestwindWebToolkit/Westwind.GlobalizationWeb/CustomerList.aspx

There’s been a lot of feedback from many folks and many small suggestions have been integrated in this update.

This sample provides an ASP.NET ResourceProvider as well as a full .NET ResoureManager (optionally as a second full ResourceProvider implementation) that uses a database for resource storage. There are a host of tools that allow for creation of resources from scratch or by importing resources from Resx files and then editing those resources interactively in a rich resource editing form where resources can be added, edited ,deleted and translated easily. Optionally resources can also be saved back to Resx and changes be displayed in real time either with data based or ResX resources.

Other features include a control that can be dropped onto any form that allows making all Localizable elements on a form jump links to bring up the context sensitive resource for editing and a  new JavaScript Resource handler  to server side resources as JavaScript a client side resource object (more on that in my next post) and creating strongly typed global resources that don’t rely on a separate ResourceManager (which is highly wasteful). There’s also been a bit of work on the Administration form’s UI easier to use and more responsive and with even fewer postbacks (there weren’t many to start with). The UI has also been updated to my jQuery based client library and it’s considerably smaller than the previous version because of it.

LocalizationForm 

Anyway, if you’ve used the previous version you’ll want to check out these updates as they provide many small enhancements. If you haven’t and you’re doing localization with ASP.NET you might check it out to see if your localization tasks can’t be a little easier.

West Wind Web Toolkit

FWIW, I’ve also started the process of consolidating all of my article samples, utilities and tools into a single set of libraries that are integrated into a single package. A number of folks have complained – rightfully so – that some of my samples don’t work well together because they reuse the same components in the same namespaces resulting in name conflicts. I use all of these components all the time, but I’ve been using a consolidated base and I’m now making that whole base package available.

I’ve thrown my entire toolkit that I use in most applications together and made it available as the West Wind Web Toolkit with live access via source repository. The library includes the Westwind.Globalization stuff as well as the samples along with all the support libraries and full code. It also includes the update to the jQuery Controls  and what was the West Wind Ajax Toolkit as well as the Web Forms two-way DataBinder and many other popular components.

The library is all there, but the sample site and docs are still under construction. If you want you can also download the globalization project and samples from the Toolkit site or the repository which will be updated frequently along with the site.

West Wind Web Toolkit for ASP.NET Site

Posted in ASP.NET  Localization  

The Voices of Reason


 

Fabrice
April 01, 2009

# Recommended

I highly recommend this resource provider. I used it for proagora.com, and it was the perfect solution we needed for localization.
Thanks for your work Rick!

satish
April 01, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Hi Rick ,
is that possible to use the Custom resource provider with the WPF application..

Aaron
April 03, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Rick-

I love this tool and was in fact about to use it as a basis for the localization effort on a project I'm currently working on (albeit a heavily modified version). As such, I was hoping to be able to use this newest version but something you didn't mention in your post is that it's now a .Net 3.5 library and my project is 2.0. Any chance you can put up the old version for download as well?

Rick Strahl
April 05, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

@Aaron - yes this new release is for .NET 3.5. There's not much that actually is 3.5 specific but the support assemblies require it.

The old version that works with .NET 2.0 is still available at:
http://www.west-wind.com/tools/wwDbResourceProvider/wwDbResourceProvider.zip

Liming
April 08, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Hey Rick:

In one part of your code, the "DesignTimeResourceProviderFactory", you have a commented out "Debug.Write()" statement.

I'm trying to do some debugging on the design time class, when I clicked "Tools->Generate Local Resource", I don't see any messages being generated out of the Debug.Write(), how did you set it up to see the output message?

I read that you need two instance of Visual Studio to debug design time classes, is that right?

Thanks

Rick Strahl
April 08, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

@Liming - debug messages only output when running in debug mode so you're not going to see anything unless you debug the component. You need two instances of Visual Studio yes. One is your development debugger, the other is the instance that is actually running the design time interface and firing into the debugger. It's painful and slow but it works :-}.

liming
April 09, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Thanks Rick.

Managed to get it to work with two instance of vs.net. Later last night, I downloaded this tool called DebugView from SysInternals inc. A free util, that pretty much made it a lot easier.

Strange thing is, I could run the application fine, but if I compile my project, from the log file of DebugView tool, I see at compile time, it actually goes out to the database?? ConfigurationManager.ConnectionStrings["blah"], simply doesn't pick up my web.config connectionStrings and such cause a compile time error for meta:key

At one point during the night, it worked though, not sure what I did differently. Debug.Write got all the connectionStrings "localSqlserver" and "blah".. Will investigate.

Anyway, Rick, thanks for your code, it really helps.

Rick Strahl
April 09, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

@liming - ASP.NET reads resource values at compile time and embeds the invariant values into the compiled pages by default. This is nice if everything works but a nightmare if the provider doesn't work because you'll get blank resources for everything which produces some interesting results. <s>

If you're using the resource provider set the key of the connectionString to that connection string value or to a full connection string. Either will work.

Stefan Bergfeldt
June 04, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Does this update solve the problem with lost localizations that I've been having?
Every once in a while, all localized texts disappeared, and I had to reset application from the admin page.

Rick Strahl
June 04, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

@Stefan - when is this happening? At runtime? Or if you are recompiling in your app.

I've seen a few instances where this happened but it's always at design time and usually due to some issue with the data not being retrieved from the database.

Since data is only retrieved once and then cached by the ResourceProvider if there is a failure it should happen immediately after the app loads (AppDomain unload/reload).

There was one multi-threading issue fixed recently for the provider load code. To grab the latest you should get out of the West Wind Web Toolkit repository.

Nariman
June 16, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Hi Rick; I wanted to thank you for your efforts in highlighting the deficiencies in the built-in providers and to provide your readership with a very-light-weight file-based alternative:
http://www.onpreinit.com/2009/06/updatable-aspnet-resx-resource-provider.html

Nore'
July 08, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Error running the install (same as in previous version)

<SQLError Package="DevSamples_DataInstall"><Error>Windows NT user or group 'NT AUTHORITY\NETWORK SERVICE' not found. Check the name again.</Error><Assembly>DevSamples_DataInstall</Assembly><Package>Package1.resx</Package><Batch>Batch8</Batch><SQL>IF NOT EXISTS (SELECT * FROM master.dbo.syslogins WHERE loginname = N'NT AUTHORITY\NETWORK SERVICE')
CREATE LOGIN [NT AUTHORITY\NETWORK SERVICE] FROM WINDOWS</SQL></SQLError>

It would be easier if you just included the .sql script in the zip rather than in a .exe

Thanks,
Nore'

Rick Strahl
July 08, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

@Nore - The installation for the Web Toolkit includes the raw SQL script as well as a registration EXE that will ignore the missing account failure.

Nag
October 19, 2009

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Hi,
Wondering ,if this software is a free version and i can use it in the project of my company.
and does it works with oracle?. then what all the changes i need to make?.

Arun
October 14, 2011

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Hey Rick,

Hope you are doing good.I jus need to clarify my scenario with you and suggest me how to implement /handle the scenario with the custom provider you have given.

scenario : Before fetching a resource value from APP_LocalResource or APP_GlobalResource i want the check a specific .resx file in APP_GlobalResource contains the key. if exists then fetch from that file in APP_GlobalResource , else fetch from the given global resource/local resource files.
Please reply me if you have any clarification .Thanks'

Regards,
Arun

Rick Strahl
October 14, 2011

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

@Arun - you really shouldn't design your application that way. Overlapping resource IDs in different files can result in all sorts of confusion and it's best to have a clear idea where which resources go.

Local resources are for Pages, Controls and other ASP.NET UI components. Global resources are meant for system messages or messages that are reused frequently in different locations like generic messages.

All that said, what you are trying to do is doable. Create a static wrapper method like GetLocalGlobalResource() and then just call Context.GetLocalResourceObject() and check for a null value, and if it is null then call GetGlobalResourceObject() (or vice versa depending on your needs). This way you can store both resource stores. There's additional overhead in that of course and it only works manually called. There's no implicit binding support for this in the UI.

Lelala
July 31, 2012

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

The problem with that approach is, in my oppinion, how would you handle multiple translators sitting in different countries working on all languages the same time on their own?
With the basic approach of using resx-files you would be stuck.
So, if you are on the enterprise level you need a fully DB-driven solution, having a great translation tool supporting your (lets say) 5 translators...

Vasil
September 26, 2012

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Hi, I am periodically getting this error message. Do you have an Idea what could be the reason?
==
System.ArgumentException: Item has already been added. Key in dictionary: 'nl-NL' Key being added: 'nl-NL' at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) at System.Collections.Hashtable.Add(Object key, Object value) at Westwind.Globalization.wwDbResourceManager.InternalGetResourceSet(CultureInfo Culture, Boolean createIfNotExists, Boolean tryParents) in D:\Projects\BlueInkt\BlueInkt.Core\Westwind.Globalization\wwDbResourceManager.cs:line 129 at System.Resources.ResourceManager.GetObject(String name, CultureInfo culture, Boolean wrapUnmanagedMemStream) at System.Resources.ResourceManager.GetObject(String name, CultureInfo culture) at Westwind.Globalization.wwDbResourceProvider.System.Web.Compilation.IResourceProvider.GetObject(String ResourceKey, CultureInfo culture)
==

Thanks

Luis Rosa
April 04, 2013

# Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Rick , Thank you very much for this great work .
I just want to share how I solved a problem when updating to this new 1.5 version. Generating local resource was not doing any insert. I debugged and I got null on the cast :
DbResourceProviderSection Section = TSection as DbResourceProviderSection;
Somehow visual studio was confused with the DbResourceProviderSection type, I think it was finding two assemblies named Westwind.Globalization.
        public bool ReadConfigurationSection()
        {
            object TSection = null;
            TSection = WebConfigurationManager.GetWebApplicationSection("DbResourceProvider");
            if (TSection == null)
                return false;
 
            DbResourceProviderSection Section = TSection as DbResourceProviderSection;
            this.ReadSectionValues(Section);
 
            return true;
        }


Anyway I solved by changing web.config

<section name="DbResourceProvider" type="Westwind.Globalization.DbResourceProviderSection,Westwind.Globalization" requirePermission="false"/>

to
<section name="DbResourceProvider" type="Westwind.Globalization.DbResourceProviderSection" requirePermission="false"/>


Maybe will help someone.

Thank you again

Orry Rotem
March 31, 2014

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Luis, it did help!! :) Thanks for posting the configuration change.

Gerard
June 28, 2017

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

Rick, first of all, thank you very much for this framework to allow flexible resources. We incorporated it in our webapplication and then expanded it by using a CustomDataAnnotation to allow DisplayAttributes to make use of the same resources.

Unfortunately we now experience that when switching from language and thereby switching to another resource, the DisplayAttribute gets cached and doesn't switch to the other resource. Do you have any experience with that and did you find any solution for it?


Rick Strahl
June 29, 2017

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

@Gerard - Resources are always cached, so the only way to switch the resources used you have to unload resources. The library includes functions to unload resources. If you use DBRes() resources or our custom generated strongly typed resource using the resource provider then you can call the unload method. Otherwise you need to cause your app to reload the AppDomain where the resources are hosted (or explicitly recreate the resource manager).

Take a look at DbRes.ClearResources() which releases resources loaded through this library. But it won't help with .NET only loaded resources.


Gerard
July 02, 2017

# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET

@Rick - Thanks for your reply. Unfortunately it isn't the problem with the ClearResources - that part works well. We have a button which explicitly calls this function and it works properly, as long as we call the translation by code. So technically it is not an issue with your code, but it's something we added ourselves.

It is the part where the DisplayAttribute on a viewmodel (i.e. [Display(Name = "Articles")] gets cached - probably by MVC. In the CustomDataAnnotations we determine whether it is a DisplayAttribute and then use the Name property to translate it in the same way as rest of the application and replace the Name attribute with it. This way you can put translations on your viewmodels instead of throughout your views, which has a couple of advantages as you use some of those viewmodels more often and therefore stick to the same keys (and therefore translations) throughout your application.

Now we experience that in some cases those DisplayAttributes still contain the translated Name after switching to another language. Since the Name is already translated, we cannot find that particular key in our resource anymore to re-translate it to the new language. Simply reloading the resources does not seem to solve this issue as it appears .NET seems to cache the DisplayAttribute after the first hit.

I know it isn't part of the code you provided, but I was simply wondering if you have encountered something similar and whether you have found a solution for this, as my research online so far has not produced any solutions. I had expected more people to use this idea, but apparently that isn't the case - or I haven't found them so far.


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024