{"id":44,"date":"2011-06-20T21:52:32","date_gmt":"2011-06-21T01:52:32","guid":{"rendered":"http:\/\/blogs.visigo.com\/chriscoulson\/?p=44"},"modified":"2011-06-20T21:52:32","modified_gmt":"2011-06-21T01:52:32","slug":"deploying-localized-satellite-assemblies-with-sharepoint-2010","status":"publish","type":"post","link":"https:\/\/blogs.visigo.com\/chriscoulson\/deploying-localized-satellite-assemblies-with-sharepoint-2010\/","title":{"rendered":"Deploying Localized Satellite Assemblies with SharePoint 2010"},"content":{"rendered":"<p>Localizing web parts in a SharePoint 2010 project is pretty straight forward. Add resource files to your project, set the Deployment Type to AppGlobalResource, and then access them with <strong>GetGlobalResourceObject <\/strong>or with the <strong>&lt;%$Resources&gt;<\/strong> tag. Unfortunately this only works where you have the HttpContext &#8211; so great for web parts, but useless for Timer jobs and event receivers.<\/p>\n<p>In order to access the localized resources when there is no HttpContext you&#8217;ll need to access the embedded resource files. \u00a0If the resource file build action is &#8220;Embedded Resource&#8221;, Visual Studio will generate a satellite assembly for each locale that you have a resource file for. If you check your build output folder, you should see something like this:<\/p>\n<table class=\"easy-table-creator tablesorter\" style=\"width: 100%;\">\n<tbody>\n<tr>\n<td>MyProject.dll<\/td>\n<td><em>Main assembly<\/em><\/td>\n<\/tr>\n<tr>\n<td>fr-FR\\MyProject.resources.dll<\/td>\n<td><em>Satellite Assembly<\/em><\/td>\n<\/tr>\n<tr>\n<td>en-US\\MyProject.resources.dll<\/td>\n<td><em>Satellite Assembly<\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Great! So now that we have the resources embedded in our satellite assemblies, we can just access them with <strong>Resources.MyResource.Key<\/strong> or <strong>ResourceManager.GetString<\/strong>, right? That&#8217;s what I thought, but whenever I went to retrieve the resource i&#8217;d only ever get the default value, i&#8217;d never get the localized value. \u00a0After snooping through the WSP file I realized that although the satellite assemblies are built automatically, <strong>they are not automatically packaged in the WSP<\/strong>.<\/p>\n<p>In order to access the localized resources, the satellite assemblies need to be manually added to the package:<\/p>\n<ol>\n<li>Open the Package in the SharePoint solution<\/li>\n<li>Select the Advanced Tab<\/li>\n<li>Click Add and select Add Existing Assembly&#8230; (Add Existing Assembly from Project Output&#8230; does not work)<\/li>\n<li>For the Source Path find and select the satellite assembly you&#8217;d like to add<\/li>\n<li>Leave the Deployment Target set to Global Assembly Cache<\/li>\n<li>The location will be automatically set to the name of your satellite assembly. \u00a0The locale folder needs to be appended to the location name. For example the fr-FR satellite assembly would read fr-FR\\MyProject.resources.dll.<br \/>\n<a href=\"https:\/\/blogs.visigo.com\/chriscoulson\/wp-content\/uploads\/2011\/06\/satelliteassembly1.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Adding Satellite Assembly\" src=\"https:\/\/blogs.visigo.com\/chriscoulson\/wp-content\/uploads\/2011\/06\/satelliteassembly1.png\" alt=\"Adding Satellite Assembly\" width=\"454\" height=\"500\" \/><\/a><\/li>\n<li>Click OK (Safe Controls and Satellite Resources do not need to be added)<br \/>\n<a href=\"https:\/\/blogs.visigo.com\/chriscoulson\/wp-content\/uploads\/2011\/06\/satelliteassembly2.png\"><img loading=\"lazy\" decoding=\"async\" title=\"Satellite Assembly Added\" src=\"https:\/\/blogs.visigo.com\/chriscoulson\/wp-content\/uploads\/2011\/06\/satelliteassembly2-500x263.png\" alt=\"Satellite Assembly Added\" width=\"500\" height=\"263\" \/><\/a><\/li>\n<li>Repeat for each Satellite Assembly in your project<\/li>\n<\/ol>\n<p>After deploying the modified package, you should now be able to access your localized resources.<\/p>\n<h4>Gotchas<\/h4>\n<p>One problem with this solution is that the path to the satellite assemblies is hard coded. So when you switch from a Debug to Release configuration (or vice-versa), you now have to modify each of the satellite assembly entries to point to the new location. Microsoft suggests that if you will be changing configurations often, you should add a post-build step that copies all of the satellite assemblies to a specified folder and then references that copy of the assemblies in the package.<\/p>\n<h4>More Info<\/h4>\n<p><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/gg615453.aspx\">http:\/\/msdn.microsoft.com\/en-us\/library\/gg615453.aspx<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Localizing web parts in a SharePoint 2010 project is pretty straight forward. Add resource files to your project, set the Deployment Type to AppGlobalResource, and then access them with GetGlobalResourceObject or with the &lt;%$Resources&gt; tag. Unfortunately this only works where you have the HttpContext &#8211; so great for web parts, but useless for Timer jobs [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[52,5],"tags":[73,71,70,72,66,64,76,54,67,74,68,22,24,69,75],"class_list":["post-44","post","type-post","status-publish","format-standard","hentry","category-localization","category-sharepoint","tag-appglobalresource","tag-assemblies","tag-deployment","tag-getglobalresourceobject","tag-global-assembly-cache","tag-localized","tag-package","tag-resource","tag-resource-files","tag-resourcemanager","tag-satellite-assemblies","tag-sharepoint-2","tag-sharepoint-2010","tag-visual-studio","tag-wsp"],"_links":{"self":[{"href":"https:\/\/blogs.visigo.com\/chriscoulson\/wp-json\/wp\/v2\/posts\/44","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.visigo.com\/chriscoulson\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.visigo.com\/chriscoulson\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.visigo.com\/chriscoulson\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.visigo.com\/chriscoulson\/wp-json\/wp\/v2\/comments?post=44"}],"version-history":[{"count":0,"href":"https:\/\/blogs.visigo.com\/chriscoulson\/wp-json\/wp\/v2\/posts\/44\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.visigo.com\/chriscoulson\/wp-json\/wp\/v2\/media?parent=44"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.visigo.com\/chriscoulson\/wp-json\/wp\/v2\/categories?post=44"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.visigo.com\/chriscoulson\/wp-json\/wp\/v2\/tags?post=44"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}