We are writing an ASP.NET MVC application and every once in a while we need to add a string to a description or a note that is not generated by the UI to a database record. For example, if we need to reverse a transaction, we will prepend the word 'Reverse' to the description of the original transaction.
What is the best way to go about localizing these strings we have to add every now and again? On the web project we are using resource language files so everything is really taken care of by the .net framework. Can you get a class library project (the business layer) to take advantage of the automatic localization like a web project as well?
What we usually do is having additional resource files in the back-end projects. Usually they don't grow that big, so I think it's safe to do that. Usually, you can then access those resources like this:
string dummy = Properties.ResourceFileName.Reverse;
If you add a resource file in Visual Studio, the IDE will take care of generating the required code-behind to make that work.
For your example, I would suggest you having a string like this:
Reverse {0}
Then replace {0} with the actual transaction description. This way the translator will be able to move {0} before "Reverse" in case the specific language requires it. This is just an example, but best practices suggest us to avoid concatenating localizable strings as they may break in different languages. Example:
string dummy = string.Format(Properties.ResourceFileName.Reverse, transactionDescription);
Related
I need to translate an existing ASPNET MVC application to multiple languages. I created a Resources folder and I was planning on adding resource files (resx), moving all the text to said resource files and referencing them in the views and models where needed.
Is this a good approach? If it is, should I make one resource file per controller? A global one with everything?
I imagine having one resource file per controller makes it easier to maintain, but adding a new translation would mean creating hundreds of new files.
On the other hand, having everything in one file might have a negative effect performance-wise.
What should I do?
You can add resource files with different cultures. Set the access modifiers in resource file to public.
Resource file will have name and value field. In name field define key and in value column provide the value in your language.
And use the key in razor pages and Custom messages in ur programs.
(Note that, for all resource files, the key will be same and the value will be change with the language)
I'm using a custom route in my ASP.NET MVC app (/lang/{culture}/{controller}/{action}/{id}) and in my base controller, I'm detecting the presence of a value for the culture parameter and setting the current thread culture. However, if someone manages to navigate to a language that doesn't have any resources, rather than silently falling back to the default culture, I want to present a message indicating the lack of language support.
How can I detect if the current culture has no resources specified rather than silently falling back to the default?
The issue is that in practice it's complicated to programmatically determine whether you have localizations for a given culture. You may have satellite assemblies for a given culture for one assembly, but not for another. And worse, one satellite assembly may contain translations for some resources, but not all. This may be intentional: for en-GB you may prefer to only take an "override rather than duplicate" approach and define only a few resources here and there, only where you differ from your base English.
So the simplest and clearest approach may be to maintain a hard-coded master list of supported cultures in your application code, and then just base your language support alerting logic on this list. When you add a new localization, you'll need update that list in code. But most of us do localization by checking-in new resource files into the solution anyway--there already isn't a complete separation between code and localized resources.
There doesn't seem to be a direct API to give you the list of available cultures from the resource files.
One possible solution is to enumerate the resource files and parse out the language code.
Take a look at this SO question: Get available languages from resource
We're currently debating two strategies of localization:
A. Have an XML file for the structure of the business objects with a Localized key to a separate CSV file for the translation.
for eg. /Resources/Schema.xml
in a separate CSV file: we have all key/value pairs for the translations:
/Resources/Localized.txt
Model_Title, Title, Title (in French), ...
This way, when the structure changes, we just change XML once while the LocalizedKey's are in place.
B. Have separate XML files for each language based on Culture.
eg. have two files:
/Resources/en-US/US-Localized.xml
/Resources/fr-AU/AU-Localized.xml
This way, they will have same schema but separate files. Therefore the user would have to make sure that the schemas are the same as they would need to change it twice as opposed to Option #1 where they can just change it once.
However, the readability here is much better since the user would not have to track the key the make the changes.
What are your thoughts/ideas on the strategies I suggested?
Thanks,
It is not clear about the environment -- web? desktop? internal enterprise integrated something-or-other? Is there any particular reason you aren't using whatever i18n framework your tool chain supports (gettext, .NET resource files...)?
In general I'd say you want to separate out resources by culture (but to be honsest, fr_AU should be rare) to have better maintainability and do not have to load the entire file for all per-culture-versions in many situations. This is especially true if your number of supported languages/cultures goes into the dozens or more.
However, it would be important to accommodate XML schema changes. The XML could be auto-generated, from simpler structures (key-value, either in a database or files) and validated via a common schema.
This is whether (as commenters noted) you are providing localized products or customers can create their own localizations.
In general, you should consider existing tools, rather than start from the scratch.
In .net we are using Data Driven ASP.NET Localization
Resource Provider and Editor Created by rick strahl
I am currently working on a project that requires Static Text to be configurable(including labels, messages, and validation errors). I was wondering what the best approach would be. The app is being written using ASP.NET MVC and C# 3.5. I need all this static configurable text to be fed to the MVC project from a different project. I thought of using Global Resources, or using an XML file that would be loaded on application start. By the way, this is not about localization, also static text won't be configurable by the end-user.
You could use AppSettings and web.config as James answered. you could also store it in a database, with key value pair structure.
But you also need to get it from the configuration project to the ASP.Net MVC project. I would do it like this:
Create a service interface on the configuration project
use Enterprise Library Caching in the ASP.Net MVC project
Check if the value is cached
If not get it from the configuration and store it in the cache
I would probably make a separate project that contained a series of Resx files, these are pretty easy to work with and give you localization for free. This is where I would start and if you need to edit them on the fly through some admin tool then you could use something like Rick Strahl's data driven provider. This is probably a better approach then trying to come up with your own DB driven design.
I do agree that you probably need to clarify a bit of how and when the text will be editable.
Definitely stay away from the web.config and appsettings unless we are only talking about 1 or 2 lines of text. In general this is not a good idea for many of the reasons others have stated about app restarts and just general config bloat.
I would store it in the AppSettings section in the Web.Config file.
Localization is actually a decent way to handle this--it is solving the same problem, you'd just need to provide a single language file. Downside is that localization bits are not necessarily easily end-user editable. Which drives me to the fact that the real question to answer here is "how user editable is this information going to be?" If the answer is "frequently and easily" then you might want to make some sort of UI Snippets table in your database and handle it accordingly. Another decent option would be to use a custom configuration section and read/write to it using the configuration API. Also leaves open hand-editing XML files if need be.
I would use a XML file with a single load at the application startup
There are a number of questions on this site related to how to access RESX files in an ASP.NET MVC application, and best practices of using them.
However after reading (for the first time I might add) the MSDN article on resources I'm left wondering if there are even any advantages of using RESX files since I'm not going to be using server controls. Theres all this talk of 'implicit' and 'explicit' localization but I'm not going to benefit from that with MVC.
Ultimately my application will need string resources for buttons and menu items and also much longer HTML items for longer miscellaneous content. I would like to use a CMS for the longer items becuase I'm pretty sure I don't want to go sticking them into an RESX file.
Are there any compelling reasons to use or not to use ASP.NET resources in a new application. I'm going to assume that any future MVC enhancements or RESX enhancements will work in harmony together, but for now I'm just getting a glorified IDictionary as far as I can see.
Should I proceed with RESX or look elsewhere? Should I even be considering a CMS for the kinds of resources that RESX is designed for?
Any lessons learned would be appreciated.
There are couple of advantages to the RESX infrastructure:
you don't have to load the proper per-language resources. Once the locale of the thread is established, the CLr takes care of finding the appropriate assembly and loading the resources.
it is easy to hand off the locale-specific resources for localizations to third-parties.
there is a default fallback mechanism for non-localized resources.
There is also one particular disadvantage to the RESX approach:
it is hard to support translation model where the users translate your resources for you.
I'd like to elaborate a bit about that last point. Take for example the Facebook translation model. Facebook has fairly simple way for people to provide and vote on translations of various resources. If these are stored in a database, it would be possible to use them after the proper editorial process without rebuilding and redeploying the application. With the RESX model, the resources assemblies will have to be rebuild and redeployed, which could have high enough cost depending on the deployment process.
Thus, before deciding what localization process to use, I would look at the decision of who is going to do the localization and what the deployment process for the localizaed resources would be after the main application is already deployed.
EDIT: I forgot to mention that these considerations are orthogonal to the ASP.NET framework choice (MVC or WebForms).
I'd say "yes", resx files are still a good option for new applications. I don't think ASP.NET MVC in particular changes anything about storing your strings.
What's great about using resources is
they're pretty easy to manage
localizing your site is a much easier task than without resources (and I stress much easier)
you can replace the resource store at any time because resources use the provider model. You can switch out resx files for db entries without changing the implementation of your site.
I recommend resource files for the "site strings" which are different than the large blocks of data you might edit on a frequent basis. So for a full recommendation, I'd say use resource files (resx to start) for buttons, labels, etc, and a CMS for the meaty content.
If you are going to use Resx and not use Server Controls as you are in MVC, why not extend the MVC Helper methods so you can create localised labels and text? Then simply call the text from resource in the helper method.
e.g.
'<%=Html.CultureLabel("ResouceId") %>'
or
'<%=Html.CultureButton("Name","ResouceId", HtmlButtonType.Button) %>'
Just a thought.
Also managing globalisation of a site is MUCH easier with resx for the text.