I wanted to publish this article months ago, back to the time I found this solution. But I did not mostly because of a lack of free time. Sebastien LEVERT, a top SharePoint developer and a member of Montreal’s SharePoint community, recently published a post about the same subject. Read it (sorry it’s in French), I’ll write my post so it is complementary. http://www.pimpmysharepoint.com/2014/01/09/deployer-des-fichiers-de-ressources-simplement/
To quickly summarize, when you develop SharePoint solutions and you want to support multiple languages (localize it) you need to use .net resources. These resx files are a mechanism coming from asp.net and work as a dictionary (key/value). You have to create one file by supported language. Instead of writing texts in the code (which is a bad practice anyway), you now reference these by defined keys.
Due to certain technical constraints SharePoint has two main deployment locations:
- Hive\config\resources: for texts used in web pages, user controls etc
- Hive\resources: for texts used in workflows, timerjobs, etc (the “hidden” part of the solution)
SharePoint also has two other locations related to previous ones:
- Hive\admin\resources: for central administration web site.
- App_GlobalResources: in each web application, is a copy of hive\config\resources (you can trigger the copy with command stsadm –o copyappbincontent)
You can deploy your “web” resources directly to App_GlobalResources directory. It saves administrative work ofr our itpro’s when deploying the solution. Sébastien explains that in his blog, he also explains a method to deploy the same resource file to App_GlobalResources and hive\resources. It allows you to use your resources files in a simpler way from every part of your solution (in your timerjobs and/or in your application pages for example). Indeed if often comes to a situation where you need to use the same string at multiple places, forcing you to make copies. Sebastien’s solution is a good trick and I recommend it unless you have the same constraint I’m going to explain right after.
I’ve recently been involved in a SharePoint product development. This products adds a new service application and a new service to SharePoint. During tests preceding RTM, I wanted to try something: run the service on an applicative server.
Indeed, this is a prevalent case for medium/big sized SharePoint farms: part of the servers is dedicated handling users’ requests (web front ends) and another part to heavy workload, apps servers.
We were surprised to discover that our solutions containing resources directly deployed to App_GlobalResources were only deployed to WFE’s: servers with Microsoft SharePoint Web Foundation service enabled. That caused our dll’s not to be deployed to apps servers and the service wasn’t starting properly.
I had to find a way to be able to use resources within pages without deploying files to App_GlobalResources.
First part of the solution came from this codeplex project http://spexpressions.codeplex.com/ which allows developers/integrators to use more SharePoint context variables inside pages.
Here is the solution:
- A few entries in web.config to tell IIS there is a new expression to interpret
- A class to treat this new expression
- A feature to add/delete these entries to web.config
- Resources files deployed to hive\resources
As always I’m providing you a downloadable example attached to this post.
Advantages of this method:
- Only one file deployed
- Your solutions are deployed globally (except if something else forces it to deploy per web application)
- More complex
Note: the solution I’m providing is for SharePoint 2010, but it works just fine for 2013, our product is on both versions.