Best way to make website for multiple languages - c#

I have made a website using(Asp.net, c#) and its content in English.
Now i have a requirement to make this website in such a way that is support multiple languages ie (German,French).
Lable/Textbox/ string all values will display respective selected languages
While searching i came to know there are some ways like
Using localization
Use resource file.
Database(every thing is saved in database for different language).
frankly speaking I am not agree with 3rd option.
I want to know which is the best way to go or is there any other better way?
Note:Current Website was built using .NET framework 4.0/ vs 2010.
Thanks

Resx:
http://msdn.microsoft.com/en-us/library/ms227427.aspx
http://dreamdotnet.blogspot.com/2007/01/tutorial-translating-aspnet-web.html
You can use resx files for multiple languages and use the ResXResourceWrite to update them (if you want users to be able to update the files: http://msdn.microsoft.com/en-us/library/system.resources.resxresourcewriter.aspx)
This solution is only good for static content. If you want to be able to translate content from the database (for example if you have products stored in your database, and you want that the description of the product to be multilingual too). In this case you'll need to change you DB Scheme in order to support multilingual content.
PS
you can use GetLocalResourceObject("key") in order to retrieve values without using web controls.
If you're using MVC, see the following question: How to localize ASP.NET MVC application?

Sample code i have done using resource file add global.asax
void Application_BeginRequest(Object sender, EventArgs e)
{
// Code that runs on application startup
HttpCookie cookie = HttpContext.Current.Request.Cookies["CultureInfo"];
if (cookie != null && cookie.Value != null)
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(cookie.Value);
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cookie.Value);
}
else
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en");
}
}

For dynamic content a thrid party plugin or a adding something such as Google translate would do it;
http://translate.google.com/translate_tools
FYI; Google Chrome has built in auto-translate and Chrome's popularity is growing fast... wow imagine a web where regardless of language you have access to ALL content this isn't that but I though I would share my thoughts

Related

How to set the WebBrowser object in the .NET Framework to use whatever highest version of IE is installed on the users system

So the title says it all, I would like C# code (so please, PLEASE make sure it isn't Visual Basic code). And that is all I want to ask. I have tried the web browser built in to the .NET framework, but it looks like some old version of IE (if I am right or not). And if you answered, well thanks I guess! I need this for a small project where a bot would just log on to a website (its a base for future projects).
By default it's IE7. You can bang a registry entry in to make it later:
public static void EnsureBrowserEmulationEnabled(string exename = "YourAppName.exe", bool uninstall = false)
{
try
{
using (
var rk = Registry.CurrentUser.OpenSubKey(
#"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", true)
)
{
if (!uninstall)
{
dynamic value = rk.GetValue(exename);
if (value == null)
rk.SetValue(exename, (uint)11001, RegistryValueKind.DWord);
}
else
rk.DeleteValue(exename);
}
}
catch
{
}
}
Code courtesy of this blog
The values you can use in place of 11001 can be found in MSDN
Alternatively; can you do what you want by using WebClient/HttpWebRequest rather than poking at a web browser control to navigate around? Or can you find some web service/api version of the site that will respond with JSON rather than trying to manipulate html?
I was mildly curious why you'd care what a page looks like if it's a bot that is using it, but perhaps you're hitting a "your IE is too old" from the server..

How to click on a link using Webkit Browser?

I want to click on link after navigating to a website
webKitBrowser1.Navigate("http://www.somesite.com");
How to click on a link on this website assuming that the link's id is lnkId ?
Go to Google
In the default browser control that comes with Visual Studio, I can do that using the code below :
foreach (HtmlElement el in webBrowser1.Document.GetElementTagName("a")) {
if (el.GetAttribute("id") == "lnkId") {
el.InvokeMember("click");
}
}
What is the equivalent of the code above when I'm using WebkitDotNet control?
As the WebKit doesn't provide a Click() event (see here for details), you cannot do that in the above way. But a small trick may work as an equivalent of the original winforms way as below:
foreach (Node el in webKitBrowser1.Document.GetElementsByTagName("a"))
{
if (((Element) el).GetAttribute("id") == "lnkId")
{
string urlString = ((Element) el).Attributes["href"].NodeValue;
webKitBrowser1.Navigate(urlString);
}
}
Here what I am doing is casting the WebKit.DOM.Node object to its subclass WebKit.DOM.Element to get its Attributes. Then providing href to the NamedNodeMap, i.e. Attributes as the NodeName, you can easily extract the NodeValue, which is the target url in this case. You can then simply invoke the Navigate(urlString) method on the WebKitBrowser instance to replicate the click event.
I don't work with Windows and all my experience is on Webkit GTK. Following comments are based on that experience.
I am not sure which webkit .NET version you are using. Looks like there are multiple implementations. Assuming you are using the one mentioned by Wasif, you can evaluate javascript as mentioned in the example https://code.google.com/p/open-webkit-sharp/source/browse/JavaScriptExample/Form1.cs.
Actually if implementation is supporting javascript execution then you can do most, if not all the DOM operations. The API functions are usually same as javascript functions and most of the time call exact same functions internally despite of origination. Communication between your application and javascript can be little challenging, but if you can read alert messages, that also can be solved. It looks like this library does support alert handling mechanism. A tool I wrote at https://github.com/nhrdl/notesMD will show some examples of achieving this communication though it uses GTK version and is written in python.
Incidentally if you know the id of the element, then Document.GetElementById will save you the loop.
webKitBrowser1.StringByEvaluatingJavaScriptFromString("var inpt = document.createElement(\"input\"); inpt.setAttribute(\"type\", \"submit\"); inpt.setAttribute(\"id\", \"nut\"); inpt.setAttribute(\"type\", \"submit\"); inpt.setAttribute(\"name\", \"tmp\"); inpt.setAttribute(\"value\", \"tmp\"); var element = document.getElementById(\"lnk\"); element.appendChild(inpt);");
webKitBrowser1.StringByEvaluatingJavaScriptFromString("document.getElementById('nut').click();");

How to correctly iterate application settings in C# using reflection

I am trying to iterate through application properties in C# using reflection (.NET 3.5 using VS 2010). The code "works" in that it successfully gets properties. However, it always gets the property values that were defined at design time and does not see the current values in myapp.exe.config. Properties that I access directly by name do reflect what is in the .config file. Here is the reflection-based code which only sees design-time properties:
List<StringDictionary> dictList = new List<StringDictionary>();
StringCollection bogus = new StringCollection();
foreach (PropertyInfo info in Properties.Settings.Default.GetType().GetProperties())
{
if (!("logLevel".Equals(info.Name) || "eventURL".Equals(info.Name)))
{
if (bogus.GetType().IsAssignableFrom(info.PropertyType))
{
StringCollection rawConfig = (StringCollection)info.GetValue(Properties.Settings.Default, null);
// do something
}
}
}
This code does pick up the current values in myapp.exe.config.
String logLevelStr = Properties.Settings.Default.logLevel
What am I doing wrong in my reflection code that causes me to pull only the properties defined at design time and not what is currently in myapp.exe.config?
To get the current value you need to use something like this which looks at Default.PropertyValues instead of Default.Properties
foreach (SettingsPropertyValue property in Properties.Settings.Default.PropertyValues)
{
Debug.WriteLine(string.Format("Property {0}'s value is {1}",property.Name,property.PropertyValue));
}
// note: the above may not work in some multi-form app, even if the applicaton prefix is prepended in front of Properties esp for visual studio 2010 compiled app with .net frame work 4
I think that there is a fundamental misunderstanding here. Settings can be one of two types- Application settings and User settings.
Application settings are intended to be written only at design time. As Henk points out it is possible to edit them after deployment if you are admin, but that isn't really the intent. Also, it should be noted that while Application settings are stored in the .config file, they are only read once and then cached in memory. That's why you don't see the new values when you edit the file.
User settings can be overwritten at run time by application code and saved, but they are saved at a user scope, so a different user running the same application can have different values. The intention there was things like user preferences. There is a drop down in the settings designer grid to switch between Application and User scope for each Setting.
Either way, you shouldn't be accessing them via reflection.
There must be some kind of misunderstanding here.
If you want to read the configurations from myapp.exe.config you should use ConfigurationManager. This class allows you to access AppSettings and ConnectionString directly through static properties or read custom sections by the GetSection method.
Beside, application configurations are meant to be design-time only. You shouldn't alter myapp.exe.config at runtime. Never. This file must be the same for each execution of your application.
Beside, what is Properties.Settings.Default.logLevel ???
Consider:
foreach (SettingsProperty sp in Settings.Default.Properties)
{
Console.WriteLine(sp.Name + "=" + Settings.Default.Properties.Default[sp.Name].ToString());
}

Multilanguage Support In C#

I've developed a sample software in c# windows Appliation. How to make it a multilingual supporting software.
For Example: One of the message boxes display " Welcome to sample application"
i installed the software in a chinees os , but it displays the message in english only.
i'm using "string table" (Resource File) for this problem.
In string table i need to create entry for each messages in english and Chinees.
its a timely process. is there any other way to do this?
Create Resources files for each language you want to give support for mentioned below.
alt text http://geekswithblogs.net/images/geekswithblogs_net/dotNETPlayground/resx.gif
Based on the language/currentculture of the user, read values from respective Language Resource file and display in label or MessageBox. Here's some sample code:
public static class Translate
{
public static string GetLanguage()
{
return HttpContext.Current.Request.UserLanguages[0];
}
public static string Message(string key)
{
ResourceManager resMan = null;
if (HttpContext.Current.Cache["resMan" + Global.GetLanguage()] == null)
{
resMan = Language.GetResourceManager(Global.GetLanguage());
if (resMan != null) HttpContext.Current.Cache["resMan" + Global.GetLanguage()] = resMan;
}
else
resMan = (ResourceManager)HttpContext.Current.Cache["resMan" + Global.GetLanguage()];
if (resMan == null) return key;
string originalKey = key;
key = Regex.Replace(key, "[ ./]", "_");
try
{
string value = resMan.GetString(key);
if (value != null) return value;
return originalKey;
}
catch (MissingManifestResourceException)
{
try
{
return HttpContext.GetGlobalResourceObject("en_au", key).ToString();
}
catch (MissingManifestResourceException mmre)
{
throw new System.IO.FileNotFoundException("Could not locate the en_au.resx resource file. This is the default language pack, and needs to exist within the Resources project.", mmre);
}
catch (NullReferenceException)
{
return originalKey;
}
}
catch (NullReferenceException)
{
return originalKey;
}
}
}
In asn asp.net application, you'd use it as following:
<span class="label">User:</span>
You now would put:
<span class="label"><%=Translate.Message("User") %>:</span>
If you were going to use resource files as Ram suggested, there is a good blog post about localisation
here: ASP.NET MVC 2 Localization complete guide. (I should have mentioned that this is for Asp.net mvc 2, it may or may not be useful) You still have to spend time making tables for each language. I have not used any other approach for this before, hope you find something useful
You can do it using resource files. You need to create resource file for each language and you can use the appropriate one while running the application.
Resharper 5.0 can greatly improve the time you spend on localization. It has features that allows easy move to resource and it underlines (if chosen so) all strings that are localizable so it's harder to miss them.
Given that it has 30 days trial (full version) you can simply install it, do your job and uninstall if you can't afford it, but i would suggest to keep it :-) It's really worth it's price.
Software localization and globalization have always been tough and at times unwanted tasks for developers. ReSharper 5 greatly simplifies working with resources by providing a full stack of features for resx files and resource usages in C# and VB.NET code, as well as in ASP.NET and XAML markup.
Dedicated features include Move string to resource, Find usages of resource and other navigation actions. Combined with refactoring support, inspections and fixes, you get a convenient localization environment.

Best way to bind Windows Forms properties to ApplicationSettings in C#?

In a desktop application needing some serious re-factoring, I have several chunks of code that look like this:
private void LoadSettings()
{
WindowState = Properties.Settings.Default.WindowState;
Location = Properties.Settings.Default.WindowLocation;
...
}
private void SaveSettings()
{
Properties.Settings.Default.WindowState = WindowState;
Properties.Settings.Default.WindowLocation = Location;
...
}
What's the best way to replace this? Project-imposed constraints:
Visual Studio 2005
C# / .NET 2.0
Windows Forms
Update
For posterity, I've also found two useful tutorials: "Windows Forms User Settings in C#" and "Exploring Secrets of Persistent Application Settings".
I've asked a follow-up question about using this technique to bind a form's Size here. I separated them out to help people who search for similar issues.
­­­­­­­­­­­­­­­­­­­
If you open your windows form in the designer, look in the properties box. The first item should be "(ApplicationSetting)". Under that is "(PropertyBinding)". That's where you'll find the option to do exactly what you want.

Categories