Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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.
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
Other Posts you might also like
The Voices of Reason
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
is that possible to use the Custom resource provider with the WPF application..
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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?
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
The old version that works with .NET 2.0 is still available at:
http://www.west-wind.com/tools/wwDbResourceProvider/wwDbResourceProvider.zip
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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.
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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.
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
Every once in a while, all localized texts disappeared, and I had to reset application from the admin page.
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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.
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
http://www.onpreinit.com/2009/06/updatable-aspnet-resx-resource-provider.html
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
<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'
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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?.
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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.
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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...
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
==
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
# Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
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
# re: Updated Westwind.Globalization Data Driven Resource Provider for ASP.NET
# 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?
# 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.
# 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.
# Recommended
Thanks for your work Rick!