Abp boilerplate Localization by QueryStringRequestCultureProvider for custom language - localization

I try to use localization method L() in MyController for getting localization string from my custom added language(not standart for boilerplate - swedish).
Regarding to documentation (https://aspnetboilerplate.com/Pages/Documents/Localization)
I can add queryStringParameter to request culture=sv (my source localization file is Abp-sv.xml)
I added this parameter but L("SomeString) returns localization for default language.
If I use culture for standart ASP.NET Boilerplate languages ar, de, etc. then it works.

Thanks for #aaron
It didn't work because my DB doesn't include row with my custom language. queryStringParameter works just in case if you add your language to application.
You can do it just by this code
Configuration.Localization.Languages.Add(new LanguageInfo("en", "English", "famfamfam-flags gb", true));
Or as in my case, by adding it to DB, and abp'll add it in your application.

Related

MVC5 reading Config values without using System.Web

I keep reading that the new MVC avoids using System.Web by default as that used to add lots of extra stuff automatically.
Does that mean that in order to read the config file now in MVC5,
one should use from System.Net instead?
Thanks...
It should be:
string key = System.Configuration.ConfigurationManager.AppSettings.Get("AppKey");
OR
string key = System.Configuration.ConfigurationManager.AppSettings["AppKey"];
I read somewhere in a Microsoft example where they imported
using System.Configuration;
and then use the standard
ConfigurationManager.AppSettings["MyKey"]
Just thought to post this in case somebody has the same question/problem

Access resource bundle outside struts action class

There are several ways to handle resource bundle using Struts 2.3 framework. This includes using certain UI tags in the View class or getText() method in your Action class.
However, there is no straight-forward mechanism to access this resource bundle in a java class or any other class except View and Action.
I found two ways to access it in a java class,however, they fail to completely replace the old MessageResources of Struts 1.2 framework.
Following are the two ways with drawback of each
Using ResourceBundle class of java.util package.
Locale locale = (Locale)request.getSession().getAttribute(ConstantsFnl.LOCALE_KEY);
ResourceBundle rb = ResourceBundle.getBundle(bundle,locale);
message = rb.getString(key);
The drawback with this approach is you cannot pass an array of arguments which can be replaced in your message text.This functionality was present in Struts 1.2 with MessageReosurces.
Using DefaultTextProvider of Struts 2.3 framework.
DefaultTextProvider dtp = new DefaultTextProvider();
return dtp.getText(key, (String[])params);
Though this approach gives you a way to pass an array of arguments to be replaced in your message text, it does not give you a mechanism to specify the locale or specify the bundle to be searched.Again,this functionality is present in Struts 1.2 with MessageResources class.
Looking for an optimum approach.Any help on this would be great.
You can use methods found in:
com.opensymphony.xwork2.util.LocalizedTextUtil

How should I store localized Strings in an iOS project?

I’m developing an iOS application. One of my tasks is localization. For this reason, I’ve taken all strings and put them each in a NSLocalizedString(key,comment), and everything’s been OK.
But my new solution is to create a Singleton class, which stores every String that I use in the project. With this I have one small, but tricky problem: naming. Do I need to create some dictionaries for every class (view) that needs localized strings? Or should I use prefixes for this, or functions that return objects with good, understandable property names?
P.S: i don't want to invent new wheel. I want to create STORAGE of localized strings, that will be used in project. So, my target is to make singleton:
[[[StringStorage sharedInstance] getStringsForClass:self] objectForKey:#"title"];
or something like this:
[StringStorage sharedInstance].stringTitleForMainView
You really should stick with NSLocalizedString and NSLocalizedStringFromTable. You also can use the NSBundle method localizedStringForKey:value:table:.
But if you take any other route you are reinventing the wheel, and you lose the ability to use the genstrings command line tool to extract all your strings from the source code.

How do you inject your dependencies when they need differents parameters?

For instance I have this bit of code
public class ProductService{
private IProductDataSource _dataSource = DependencyManager.Get<IProductDataSource>();
public Product Get(int id){
return _dataSource.Select(id);
}
}
I have 2 different data source:
XML file which contains the informations only in 1 language,
a SQL data base which contains the informations in many languages.
So I created 2 implementation for IProductDataSource, for for each kind of datasource.
But how do I send the required language to the SQL data source ?
I add the parameter "language" to the method "IProductDataSource.Select" even if I won't use it in the case of the XML implementation.
Inside the SQL implementation I get the language from a global state ?
I add the language to the constructor of my SQL implementation, but then I won't use my DependencyManager and handle my self the dependency injection.
Maybe my first solution is not good.
The third option is the way to go. Inject the language configuration to your SQL implementation. Also get rid of your DependencyManager ServiceLocator and use constructor injection instead.
If your application needs to work with multiple languages in a single instance I think point one is a sensible approach. If the underlying data does not provide translations for a request language then return null. There is another solution in this scenario. I'm assuming that what you have is a list of products and language translations for each product. Can you refactor your model so that you do not need to specify or asertain the langauge until you reference language specific text? The point being a product is a product regardless of the language you choose to describe it. i.e. one product instance per product, only the product id on the Datasource.Select(..) method and some other abstraction mechanism to deal with accessing the correct text translation.
If however each instance of your application is only concerned with one language set I second Mr Gloor.
First of all I need to point out that you are NOT injecting any dependencies with your example - you are depending on a service locator (DependencyManager) to get them for you. Dependency injection, simply put, is when your classes are unaware of who provides the dependencies, e.g. using a constructor, a setter, a method. As it was already mentioned in the other answers, Service locator is an anti-pattern and should be avoided. The reasons are described in this great article.
Another thing is that the settings you are mentioning, such as language or currency, seem to be localization related and would probably be better dealt with using the built-in mechanisms of your language of choice (e.g. resource files, etc).
Now, having said that, depending on how the rest of your code is structured you have several options to solve this while still using Service locator:
You could have SqlDataSource depend on some ILanguageProvider which pulls the current language from somewhere. However, with more settings like these (or if it is difficult to get current language in an isolated way) this can get messy very fast.
You could depend on IProductDataSourceFactory instead (or, if you are using C#, Func<IProductDataSource>) which would return the concrete implementation with the correct settings. Again, you need to be able to get the current language in an isolated way in order to use this.
You could go with option 1 in your question. This would be a leaky abstraction but would be the simplest to implement.
However, if you decide to get rid of service locator and start using some DI container, the best solution would be using option 3 (as it was already stated) and configuring container accordingly to provide the correct value. Some good ideas of how to do this in an elegant way can be found in the answer to this question

Is it possible to extend the User.Identity structure (ASP.Net/MVC) somehow?

Is it possible to store additional data specific to the currently logged on user somehow?
Certainly! If you are not familiar with writing an extension, there are the VB.NET and C# guides on the subject.
You will need to extend the System.Security.Principal.IIdentity interface. As an example:
Declaration:
Imports System.Runtime.CompilerServices
Module Extensions
<Extension()>
Function GetMyCustomProperty(anIdentity As System.Security.Principal.IIdentity, myParameter As Integer) As Object
Return New Object()
End Function
End Module
Usage:
User.Identity.GetMyCustomProperty(4)
NOTES:
The C# code is a fair deal different so it's worth looking at the
guides on how extensions are implemented in general. Running this
code through a VB.NET => C# converter is not enough.
Extensions may only be methods. You may not program custom properties. This will likely mean implementing getter/setter methods if you want property-like behavior.
EDIT:
After seeing your comments, I assume you are doing this to provide a sort of crude functionality similar to a user profile. Consider using a profile provider in concert with any membership you are currently using if you'd like this functionality.

Resources