Apparently, my understanding of .resx files was flawed - I had assumed (without testing) that they were deployed as XML so as to remain editable at a later time - clearly, this is incorrect. So, I'm left with a gap I need to fill for the labels and format strings in our company's web application, hopefully someone here can point me in the right direction.
I'm looking for a solution that can support multiple languages, and can be edited by a system administrator at a later date. For the first requirement, resx files work perfectly - if the UI culture is changed, the appropriate resource is used, or it defaults to the top level resource if no culture specific resource is available. Unfortunately, if company A wants a resource string to be "Account Number", and company B wants that same string to be "Account ID", we have no good way to support this - we don't want to have to compile a different version of the web site for each company, just to change a few resource strings - ideally, those strings could simply be set by the company's tech person after deployment.
Is there a framework out there that will be of use here? Or perhaps a different way to approach the problem using resx files?'
You really can't use resx files for your pre-compiled solution.
There are two options:
Deploy an uncompiled version of your site.
Implement a database solution, and create an administrative area for updating the text, so a user may log in and make changes. You would be able to maintain your precompiled code.
Related
My goal is to implement the changing values of resources and give the admin the ability to maintain the language through the portal. In order to do that, I need to be able to change resx files at the runtime, because all their values are stored on the resx files. I have 3 resx files for each different language. In my case I want the translation can be maintain later by an admin at runtime. For example admin can add, edit or delete the entry for the language at runtime.
As #Xerillio mentioned in his comment this is a lot of effort.
Recently I've created a nuget that may save your time and effort. Have a look at XLocalizer, it creates resources and uses online translation services to auto translate the missing resources and save them in XML or DB, then it provides an easy interface to export them to RESX. Finally you may see XLocalizer.Samples, it contains sample setup for different scenarios.
If you need another file/DB type to store the resources, you may create your custom resource provider and register it in startup.
The DB sample provides UI to edit resources, but with XML sample I didn't create a UI for editing resources, instead you may download the XML, do your corrections if any, then upload and use the built-in exporter to export to RESX.
With this nuget, all I have to do to add a new culture even in runtime, is just to add the culture name to the supported cultures list, then do some correction to the auto translations, all the rest is handled by XLocalizer.
Notice: it was not possible to put all this in the comment, thats why I posted as answer :)
We have a legacy ASP.NET 2.0 Webforms Web Site that we need to extend. It is poorly designed, and the architecture forces many files to be duplicated.
Whenever we add new functionality we are forced to physically copy our pages+code behind for "Weekly" versions of our products to other folders for our "Daily" products. For obvious reasons, this makes updates very annoying, since we need remember to update 2 copies of each file. Although the Weekly and Daily versions can differ, this rarely happens, so they usually have to be identical and exactly in syc.
Is there a way to create links/shortcuts in Windows or Visual Studio, so that we only need to create pages for our "weekly" products, and if a page is requested from the corresponding "daily" product, ASP.NET would transparently serve the "weekly" page, unless we physically subsitute a modified "daily" page? Bonus points if we can fool VS 2012 as well.
Clarification 1: We have folders like /Products/ProductAMonthly/Price.aspx and /Products/ProductADaily/Price.aspx The products are set up in a config file, and a framework does the routing. Unfortunately, the config file forces each product into a separate folder on the server, so we can't get the config file to reuse pages.
We have also refactored into base classes, and could perhaps refactor some more, but this doesn't get rid of the need for identical pages to exist in the folders defined in the config file.
If a daily product is suppose to display the same data as the weekly, in the code behind for a Daily product, you could do a server.transfer("Url for Weekly Product")
In the event the daily product is different than the weekly, you don't use a server.transfer, and you implement the desired daily business logic.
I eventually used a Windows feature called Symbolic Links (or Junctions). ASP.NET/IIS seems to serve these up without problems. We have a batch file that uses mklink to create these on each developer's machines. We also added the junctioned files to our source control's ignore file. It seems to work well.
The challenge is to determine whether ASP.NET is enabled within IIS7 in a reliable and correct way.
Enabling/Disabling is done in this case by going into:
Server Manager ->
Roles ->
Web Server (IIS) ->
Remove Role Services ->
Remove ASP.NET
The natural place to determine this should be within the applicationHost.config file. However, with ASP.NET enabled or disabled, we still have the "ManagedEngine" module available, and we still have the isapi filter record in the tag.
The best I can find at the moment is to check if the <isapiCgiRestriction> tag includes the aspnet_isapi.dll, or that the ASPNET trace provider is available.
However these aren't detecting the presence of the ASP.NET config directly, just a side effect that could conceivably be reconfigured by the user.
I'd rather do this by examining the IIS configuration/setup rather than the OS itself, if possible, although enumerating the Roles & Services on the server might be acceptable if we can guarantee that this technique will always work whenever IIS7 is used.
Update
Thanks for the responses. Clarifying exactly what I want to do, I'm pulling settings from a variety of places in the server's configuration into a single (readonly) view to show what the user needs to have configured to allow the software to work.
One of the settings I need to bring in is this one:
The one highlighted in red.
I don't need to manipulate the setting, just reproduce it. I want to see whether the user checked the ASP.NET box when they added the IIS role to the server, as in this example they clearly didn't.
I'd like to do this by looking at something reliable in IIS rather than enumerating the role services because I don't want to add any platform specific dependencies on the check that I don't need. I don't know if it will ever be possible to install IIS7 on a server that doesn't have the Roles/Services infrastructure, but in preference, I'd rather not worry about it. I also have a load of libraries for scrubbing around IIS already.
However, I'm also having trouble finding out how to enumerate the Roles/Services at all, so if there's a solution that involves doing that, it would certainly be useful, and much better than checking the side effect of having the ASPNET trace provider lying around.
Unfortunately, if you don't check the ASP.NET button, you can still get the ManagedEngine module in the IIS applicationHost.config file, so it's not a reliable check. You can also have ASP.NET mapped as an isapi filter, so checking them isn't enough. These things are especially problematic in the case where ASP.NET was installed but has been removed.
It looks like the best solution would be to examine the Role Services. However, API information on this is looking pretty rare, hence the cry for help.
The absolute way to know if they checked that or not is to search the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp\Components
In there you should see two values set to 1, ASPNET and NetFxEnvironment and NetFxExtensibility. This registry key is the IIS Setup key that contains all the components that have been enabled in IIS.
Determining if asp.net is even an installed feature (prerequisite for enabling it) can be done through PowerShell, which implies there is .net api out there for it if you dig hard enough. The PowerShell methods:
Import-Module servermanager
Get-WindowsFeature web-asp-net
Which will return an object of type Microsoft.Windows.ServerManager.Commands.Feature. The installed property is boolean and indicates whether or not the feature is installed.
So do you want the easy way? Make a nice pretty .aspx page that displays as HTML with an error block in a div in a placeholder saying "You need to install ASP.NET" and have it change on ASP.NET being installed to instead say "ASP.NET is installed" and then just have the tool launch this webpage in the default browser after copying it to the directory identified in IIS as the *:80 site (or create the directory mapping in IIS programmatically by altering the XML and then removing it later)
May not be the most elegant but it does ensure that testing shows what features are truly installed versus what's in an XML file.
Because that will scream "do it the lazy ignorant way" I'll remind you that the only way for me to know in javascript what features I can use is to test them before I try to use them, or assume they're there and watch it blow up. My point is, it doesn't matter what gets reported in a file, it matters what you can actually use. Just because C:\Windows\Micrsoft.Net\Framework\v3.xxxxxxxx exists and has files doesn't mean the dll's are registered in the GAC, does it?
An ASP.NET project I am working on will be adding localization in the next version. As we pull text from our ASPX pages into resource files and other data into database tables, what tools might we want to evaluate to assist this process?
Are there any tools to assist translators to create the localization files?
Resource Refactoring Tool
alt text http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=ResourceRefactoring&DownloadId=3748
Microsoft "open source" Visual Studio tool that integrates with the IDE. You can easily replace every occurrence of a string with a resource reference with a few clicks.
http://www.codeplex.com/ResourceRefactoring
Zeta Resource Editor
alt text http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=ZetaResourceEditor&DownloadId=40997
A side by side editor for multiple resource file.
http://www.codeplex.com/ZetaResourceEditor/
See Resharper for localization -http://www.jetbrains.com/resharper/webhelp/Resources__Index.html
Also check “Creating a Data Driven ASP.NET Localization Resource Provider and Editor”
http://www.west-wind.com/presentations/wwdbresourceprovider/
It also includes DbResourceControl, that shows controls with Localizable attribute
From http://guysmithferrier.com/Downloads/Top10TipsI18NASPNET.pdf and
http://www.guysmithferrier.com/post/2009/05/Localizing-ASPNET-MVC.aspx
To convert your HTML controls to equivalent ASP.NET server side controls, look at the I18NRefactorings (an add-in for VS) in the download at http://www.dotneti18n.com/Downloads.aspx (folder VS2010/ASPNETSpecifics/I18NRefactorings/I18NRefactorings in the 2010 zip)that will help automate this process.
One tool I've found is RESX Synchronizer.
This is a command-line tool that synchronizes all of the keys between two resource files. For example:
resxsync homepage.resx homepage.fr-CA.resx
will copy all keys from the default .resx file to the French Canadian localization file.
Once that is done, it is only a matter of plugging in the French text.
May want to take a look at spring.net for localization (http://www.springframework.net/docs/1.2.0/reference/html/web.html#web-localization)
From the site
'Spring.Web supports several different approaches to localization within a web application, which can be mixed and matched as appropriate. Both push and pull mechanisms are supported, as well as the fallback to globally defined resources when a local resource cannot be found. Spring.Web also provides support for user culture management and image localization, which are described in the later sections.'
How can one specify the connection string in a config file of a class library and later modify this when used in a ASP.NET Web Application?
The Class library is a data access layer that has a Dataset connecting to a database based on a connection string specified in a config file (Settings.settings/app.config).
This class library is used in a web application where user inputs data and is written to the database using the DAL classes & methods exposed in the class library.
Now, I want to migrate this application from development environment to testing environment and later to production. The problem I'm facing is that after migrating to testing, the app in testing still connects to development database. I've changed the connection string mentioned in <class library>.dll.config file but this seems to have no impact.
Can someone explain the right way to achieve this? Thanks in advance for any help. Cheers.
With the .config files the name has to match the main executing assembly. For example I had a situation like yours, I needed a class library to have its settings in a .dll.config file. While it was able to reference it the actual application would not be able to read the config file because it was expecting .exe.config. Renaming the .dll.config to .exe.config fixed the problem.
In your case migrating your connection strings from .dll.config to web.config should fix your problem!
Good luck!
Joshua is partly right ... For posterity I would like to add a bit more to this answer as I have delt with the same problems on several occasions. First, one must consider their architecture. There are several issues you can run into with .config files in ASP.NET based on deployments.
Considering the architectural ramifications:
Single tier (one server):
A simple web application may be able to leverage a reference to the sites Web.config file and resolve your issues. This would be a fine solution for a single tier application. In the case of a windows application leveraged as a .exe file, the App.config will work too.
Multi-tier (more than one server):
Here is where things became a bit hairy for me the first time I was working with .config files across boundries. Remember the hierarchy of the config structure and keep this in mind (MSDN Article on .Config structure) - there is a machine.config at the root in the appropriate ASP.NET folder. These reside at each physical server. These are overridden by the site Web.config (or App.config) which are in turn overridden by subfolder .config files. If you have more than one .config file you may want to use one of the methods to pass the file path for the specific .config you want to use. More importantly, these files each may have connection information. ASP.NET's machine.config holds some for the framework ... so you should at least be senstive to the fact this is an "inheritance" chain. Second, any changes to the Web.config file once deployed will tell the application to restart. This will result in loss of state (bad if you have active users on the site). The way around this is to keep a separate .config file (e.g. connections.config) and put a reference to that file in the Web.config. This will allow you to change the connection information (e.g. password) without having to restart the application. Here is a link to more info: MSDN: Working with Configuration Files. This article lays out all the details you need to be aware of in a normal server / IIS deployed application. Keep in mind that the .config files are mainly intended for applications, not libraries. If you have several tiers, chances are you are using some communicaiton / messaging layer (e.g. WCF). This will have / allow its own Web.config. You can keep connection strings there (and encrypt them if needed), but better yet, put them in a second file referenced by the Web.config for manageability. One final point, if you are ever going to consider the cloud, .config files are wrapped for application deployments which in effect removes all of the benefits they offer in terms of "not having restart or redeploy". Azure deployments will want to consider this article to save themselves from nightmares of maintenance: Bill Lodin blog - Configuration files in Azul / Cloud. One other point on this article – great example on how to programmatically select configuration depending on deployment! Be sure to check that out if you want to add flexibility to deploy in or out of the cloud .
I hope these points saves all of you time and headaches. I know I lost a couple days of programming time dealing with these issues ... and it was hard to find all the reasons in one place why may app was not "implementing" its connection object. Hopefully this will save you all from the same fate I had.