I just began working with ASP.NET and I'm trying to bring with me some coding standards I find healthy. Among such standards there is the multilingual support and the use of resources for easily handling future changes.
Back when I used to code desktop applications, every text had to be translated, so it was a common practice to have the language files for every languages I would want to offer to the customers. In those files I would map every single text, from button labels to error messages. In ASP.NET, with the help of Visual Studio, I have the resort of using the IDE to generate such Resource Files (from Tools -> Generate Local Resource), but then I would have to fill my webpages with labels - at least that is what I've learned from articles and tutorials. However, such approach looks a bit odd and I'm tempted to guess it doesn't smell that good as well. Now to the question:
Should I keep every single text in my website as labels and manage its contents in the resource files? It looks/feels odd especially when considering a text with several paragraphs.
Whenever I add/remove something, e.g.: a button, to an aspx file I would have to add it to the resource file as well, because generating the resource file again would simply override all my previous changes to it. That doesn't feel like a reusable code at all for me.
Perhaps I got it all wrong from tutorials as it doesn't seem like a standardized matter - specially if it required recompiling the entire application whenever some change has to be done.
Best practices for ASP.NET Web Forms localization have not really changed much over the years. If you don't have much dynamic content then you can get away with implicit localization and bind web forms controls (form elements and yes, even labels) to resource files. Explicit localization is useful if you want a bit more control over where localized text is rendered in a control with multiple captions or something you've created yourself. You don't need to look very far for instructional steps from MS on how to do either of these.
Walkthrough: Using Resources for Localization with ASP.NET
If your localization requirements are more dynamic, for example, you want to easily provision new languages, centralize resources, or you need to provision new string captions on a new dimension (like per client), then you need to get a bit more creative. .NET allows you to extend the
the resource provider and you can implement a database backend that allows for easy administration of localized resources.
Extending the ASP.NET 2.0 Resource-Provider Model, Building a Database Resource Provider
Extending Resource-Provider for storing resources in the database * A more recent implementation
Or you could just roll your own!
I've also dug up a duplicate SO post. It's a few years old, but speaking from experience I believe the advice found on the referenced code project page are still true (for Web Forms): Globalization and localization demystified in ASP.NET 2.0
I hope that helps! If you have any more specific questions regarding localization please add them to your Questions or comments.
Related
We're building an ASP.NET MVC application that is yet not localizable with a lot of Data Annotations DisplayAttribute with hard-coded strings and hard-coded message strings all over the code.
Now we have a requirement that the application must be localizable, but still, we need to allow the users to customize the field displays and the texts.
So far, I'm considering using RESX files with a custom IResourceProvider. Rick Strahl has written a good article about that. In this approach, the application is developed with standard RESX files, but in runtime, when the application need the strings, the custom provider will query the DB looking for customizations and will use them when found.
Even though it seems a good solution, it doesn't seem natural. I wonder if there's some better alternative.
Is there any standard for this?
What's not natural with using static values as defaults and checking database for localized ones? For me it's nice approach, because if someone will mess recources in db and, for example, remove one of them somehow, you'll always have a default text to display.
You can always do it in different way, by using only the db-based texts to not bother about changing defaults in your code and translations in database because it's easy to miss something when resources are in few places. When I was checking code of nopCommerce maybe 2 years ago, I've seen that when they do localization with resources from database only. I'm not sure how it's done now, but you can download source code and check it.
In WinForms app I developed a year ago I was using XML files for different languages because our customer wanted to be able to allow non-technical natives to create new language files. And I created localization tool built-in into app, but for websites it's best to use database, as you already have access to this and can easily manipulate data.
You can read more about this topic in this blog post.
At my office, we have had a long-standing debate about Localization/Globalization and how to handle it. One side pushes for the Resource (.resx) file route built in to ASP.NET, one side pushes for a database driven solution. A third group believes in rolling a custom solution.
Of course, each method has its own unique benefits and disadvantages - and we've discussed it over and over, without ever coming to a real consensus.
So, I pose it to the community: in your experience, which method provides the best mix of the following as the application grows:
Maintainability
Extensibility
Performance / Scalability
In addition to just advice, we'd also be interested in any open source projects which might help to simplify the question, as well. Thanks!
Rick Strahl (An MS MVP) has a great tool kit for managing localization via the DB - offer the ability to update and modify on demand through a controlled environment and does much of the heavy lifting for you. Histoolkit offer the following features:
Data Driven Localization Resource Provider
Database driven Localization lets you store resources in a SQL Server database.
Interactive Web based Resource Adminstration provides a live Web based adminstration for that can edit and update resources while the app is running
Resource Editing Control associates icons with each localizable control and allows jumping directly to the administration form with the current resource id and locale selected.
Resx Import and Export lets you import existing Resx resources, interactively edit them with the data driven provider, then export them back out as Resx resources.
Localization Utilities like a JavaScript Resource Handler, functions to embed localized script values and much more.
He also summarises the issues very well here (Ive pasted some good bits here - not my own work!)
To Resx or not to Resx
The default resource storage mechanism in .NET
uses Resx based resources. Resx refers to the file extension of XML
files that serve as the raw input for resources that are native to
.NET. Although XML is the input storage format that you see in Visual
Studio and the .Resx files, the final resource format is a binary
format (.Resources) that gets compiled into .NET assemblies by the
compiler. These compiled resources can be stored either alongside with
code in binary assemblies or on their own in resource satellite
assemblies whose sole purpose is to provide resources. Typically in
.NET the Invariant culture resources are embedded into the base
assembly with any other cultures housed in satellite assemblies stored
in culture specific sub-directories.
If you’re using Visual Studio
the resource compilation process is pretty much automatic – when you
add a .Resx file to a project VS.NET automatically compiles the
resources and embeds them into assemblies and creates the satellite
assemblies along with the required directory structure for each of the
supported locales. ASP.NET 2.0 expands on this base process by further
automating the resource servicing model and automatically compiling
Resx resources that are found App_GlobalResources and
App_LocalResources and making them available to the application with a
Resource Provider that’s specific to ASP.NET. The resource provider
makes resource access easier and more consistent from within ASP.NET
apps.
The .NET framework itself uses .Resx resources to serve
localized content so it seems only natural that the tools the
framework provides make resource creation tools available to serve
this same model.
Resx works well enough, but it’s not very flexible
when it comes to actually editing resources. The tool support in
Visual Studio is really quite inadequate to support localization
because VS doesn’t provide an easy way to cross reference resources
across multiple locales. And although ASP.NET’s design editor can help
with generating resources initially for all controls on a page – via
the Generate Local Resources Tool – it only works with data in the
default Invariant Culture Resx file.
Resx Resources are also static
– they are after all compiled into an assembly. If you want to make
changes to resources you will need to recompile to see those changes.
ASP.NET 2.0 introduces Global and Local Resources which can be stored
on the server and can be updated dynamically – the ASP.NET compiler
can actually compile them at runtime. However, if you use a
precompiled Web deployment model the resources still end up being
static and cannot be changed at runtime. So once you’re done with
compilation the resources are fixed.
Changing resources at runtime
may not seem like a big deal, but it can be quite handy during the
resource localization process. Wouldn’t it be nice if you could edit
resources at runtime, make a change and then actually see that change
in the UI immediately?
Using Database Resources
This brings me to storing resources in a
database. Databases are by nature more dynamic and you can make
changes to data in a database without having to recompile an
application. In addition, database data is more easily shared among
multiple developers and localizers so it’s easier to make changes to
resources in a team environment.
When you think about resource
editing it’s basically a data entry task – you need to look up
individual resource values, see all the different language variations
and then add and edit the values for each of the different locales.
While all of this could be done with the XML in the Resx files
directly it’s actually much easier to build a front end to a database
than XML files scattered all over the place. A database also gives you
much more flexibility to display the resource data in different views
and makes it easy to do things like batch updates and renames of keys
and values.
The good news is that the resource schemes in .NET are
not fixed and you can extend them. .NET and ASP.NET 2.0 allow you
create custom resource managers (core .NET runtime) and resource
providers (ASP.NET 2.0) to serve resources from anywhere including out
of a database.
As you perhaps know, default method (which is actually industry best practice) for Localizing .Net Applications is using resource files (.resx in this case). If you want to use database, you would have to write your own ResourceManager.
From this, the answer should be obvious: use standard and do not reinvent the wheel.
You might be wondering why Localization via resource files became industry-wide standard. Well, there are many reasons (too many to mention here), most of them regard to Localization process. The key one is, it is painfully hard to update (i.e. fix or install) translations for database driven Localization. Just think of what you need to install it - some SQL script. You know what will happen if you send out this for translation? Or even mistakenly update it? These kind of files are not very safe to work with (and they tend to be very large), so either you would need to create some kind of generator (with resource-like file as an input, which totally bits the purpose...) or you would need to be very careful (and pray that a translator won't break the file).
That is to say, database-driven Localization is sometimes the only sensible way of doing things - this is when you need to implement so-called dynamic Localization, that is allow users to translate things or add their contents in multiple languages.
For static Localization (typical scenario) use resource files.
Localizing user interface should not be stored in database, it is preferable to use the standard resx method because this will give you the flexibility to customize the user interface of front end for each client/deployment, without the need to change the back end or store much data about each client customization in database.
Regarding data (bi-lingual data or multi-lingual data) store them in database and use whatever technique suitable for the context (table per language, or duplicate columns for each language).
using resx is the best approach for some static values that needs not to be manipulated via UI of the app but if your values needs to be updated DB driven would be the best for it. For me its still a case to case basis. But one of the blogs I have seen in the internet made the resx files updateable via user interface.. http://sandblogaspnet.blogspot.com/2009/11/updating-resource-file.html.. hope this would help you.
As all the above are true, I want to add some additional insights.
I tend to use .resx based localisation, when working on "static" projects/websites like Dashboards or other small websites, which are focused on a specific usergroup.
When working on larger and more "dynamic" projects like shops, service-offerings, etc. (esp. when content is localized - not only labels) I like to use database localisation.
When you are developing on larger projects each language is maintained by another person, who is not necessarily in your project (especially in community-projects). Thus maintenance of different languages becomes a real hassle.
On the other side providing users some good/easy UI to update their language is time-consuming as well. So try to find a good path for your project.
We’re currently evaluating development with Sitecore 6 for a project. The client already bought it, so using another CMS isn't an option. The proposed setup would have Sitecore as our site’s content data provider; which would be consumed by a site built in ASP.Net MVC 3. We’d use Sitecore’s libraries to retrieve data from the Sitecore database on the server side.
In some cases, we also may want to consume content data via client side AJAX calls. I’ve been working on prototypes for this to see what data I can get back from a custom proxy service. This service calls GetOuterXml on the item, converts the Xml to JSON, and sends back the JSON to the calling script. So far, I’m finding using this method limiting; as it appears GetOuterXml only returns fields and values for fields that were set on the specific item, ignoring the template’s standard value fields and their default values for example. I tried Item.Fields.ReadAll(), still wouldn’t return the standard values. Also, there are circular references in the Item graph (item.Fields[0].Item.Fields[0]...); which has made serialization quite difficult without having to write something totally custom.
Needless to say, I've been running into many roadblocks on my path down this particular road and am definitely leaning toward doing things the Sitecore way. However, my team really wants to use MVC for this project; so before I push back on this, I feel its my responsibility to do some due diligence and reach out to the community to see if anyone else has tried this.
So my question is, as a Sitecore developer, have you ever used Sitecore as purely a content data provider on the client-side and/or server-side? If you have, have you encountered similar issues and were you able to resolve them? I know by using Sitecore in this way; you lose a lot of features such as content routing/aliasing, OMS, the rendering and layout engine; among other features. I’m not saying we’re definitely going down this path, we’re just at the R&D phase of using Sitecore and determining how it would best be utilized by our team and our development practices. Any constructive input is greatly appreciated.
Cheers,
Frank
I don't have experience with trying to use Sitecore solely as a data provider, but my first reaction to what you're suggesting is DON'T!
Sitecore offers extremely rich functionality which is directly integrated into ASP.Net and configured from within the Sitecore UI. Stripping that off and rebuilding it in MVC is lnot so much reinventing the wheel as reinventing the car.
I think that in 6.4 you can use some MVC alongside Sitecore, so you may be able to provide a sop to your colleagues with that.
I'm looking for best practices and good ideas rather than a proper solution.
scenario: I work in a web agency and thus we are plenty of websites from several customers. They're built upon a cms we made, so websites are quite identical for the 90% of code. However, remaining 10% struggles me and my team as it involves not only the presentation layer but behavioral logics too (ex: a website1 requires simply user/pass registration while website2 needs more data, facebook connector, etc. But this is a very easy example).
Making ad hoc development for our customers is becoming painful as keep each version aligned is getting really hard for us
What I really dream to have is an extendible website that works by itself, but in which I can override a part. This behavior should sound like "look for the specific part, if it doesn't exists get the base one". The parts could be a method, a class, a page, a control, a static file.
example:
Suppose I want website2 to have an own login component, let's so imagine that we have a situation like:
/website_base
|_ login.aspx
/website1
/website2
|_ login.aspx
So, if I ask for www.website1.com I'll get /website_base/login.aspx, but if I ask for www.website2.com I'll get /website2/login.aspx
Any idea?
Thanks
PS: we work with asp.net 3.5 framework.
There are couple of ways to achieve this.
Approach 1:
1. Split the common functionality in modules and create a pluggable structure. (like DotNetNuke) Obviously this will be more time consuming initially but over the period of time it can make itself like a product.
Approach 2:
Firstly - I would create separate solution for each client for better maintainability. This will save me a lot of hassle while maintaining the source control and when one client comes back with issues and we have multiple releases for a single client.
Secondly - From my core solution, I will identify most commonly used artifacts for each layers and move them to a core assembly.
a. For example – In UI you can use themes to give different looks for each client. Have a default master page which comes with the core site structure. All client specific details like Logo, name, contact details etc… can be configured using some DB fields.
b. In Business Layer and Data Access Layer – core functionalities like Membership, Logging, CMS related Entities etc I would have as a dll
i. I will derive my client specific logic from these core classes.
Last but not the least – how you deploy your code and how your IIS VD structure looks like… I believe it will be totally dependent on how the solution is packaged.. I would create a deployment package for each client which will give them the ability to deploy it to any server wherever they want until you have specific issues about proprietary software hosting.
Look into ASP.NET MVC. It is much more extensible than Web Forms, can be integrated into your existing Web Forms application, and it is very easy to build reusable custom components like what you are describing.
Otherwise, I would suggest looking into WebParts and developing reusable custom server controls for the components that you need. This way you can encapsulate the complex functionality within a single UI control without having to write repetitive code. WebParts are also compatible with Personalization, which you can leverage to manage the variance between which sites use which controls.
I definitely recommend MVC as the way to go for building extensible .NET web applications, but learning a new technology always incurs a cost in the time it takes to understand the new paradigm. I hope this helps you.
I found a smart solution here: http://www.codeproject.com/KB/aspnet/ASP2UserControlLibrary.aspx
Check it out
I'm thinking of developing the following but wondering if it already exists out there:
I need a SQL based solution for assigning and managing localization text values for an asp.net site instead of using RESX files. This helps maintain text on the site without having to take it down for deployment whenever an update is required.
Thanks.
We actually went down that path, and ended up with a really really slow web site - ripping out the SQL-based translation mechanism and using the ASP.NET resources gave us a significant performance boost. So I can't really recommend you do that same thing.... (and yes - we were caching and optimizing for throughput and everything - and the SQL based stuff was still significantly slower).
You get what you pay for - the SQL based approach was more flexible in terms of being able to "translate" on the fly, and fix typos and stuff. But in the end, in our app (Webforms, .NET 2.0 at that time), using resources proved to be the only viable way to go.
We did this (SQL-Based Translation) and we are really happy with the result! We developed an interface for translation-agencies to perform the updates to the page online. As a side effect, the solution started to serve as content-management system. If you cache your data, performance is not an issue. The downside is, that we invested multiple hundreds of hours into our solution. (I would guess sth. arround 600 hours, but I could check.).
We ended up with a hybrid solution where users could edit content into a database but the application then created a .resx which was deployed manually.
You could also bypass the server translation altogether and do translation in jQuery on the client which is an approach I have used successfully.
I'm not sure about the website restart, but at least using .NET MVC is very convenient and I haven't noticed that restart problem, and, if occurs, how often you need to update the resx files? For bigger projects I use to create a solution with multiple projects, one for the localization, something like this:
MyApp.Localization
Model
Page
File1.resx
MyApp.Core
MyApp.Web
Then in the Web project I add a reference to the Localization project, and use it like
#MyApp.Localization.Model.Customer.CustomerName
#MyApp.Localization.Page.About.PageTitle
#MyApp.Localization.File1.Paragraph1
Everytime I change the translated text, I either upload an updated .dll or copy the .resx files.
NOTE: You need to set your resx files to PUBLIC, so can be accessed as strongly typed.
I created a SQL based translation scheme. But I only load the needed translations for a given page when it is requested, and just the ones for that particular page.
Those get loaded into a dictionary object when the page reloads and cached during the session. Then is just does text replacement based off a lookup on that.
Pretty much all of it is dynamically generated, and includes user defined content that must be translated, so the flexibility is key.
Performance is quite fast, the SQL queries to retrieve all the data take much longer (relatively speaking).