For my first MUI series post, I’ve chosen the sandboxed solution. It’s the easiest to explain and resource paths don’t complicate things here.
Useful links:
Step 1: Create the Project
- Open Visual Studio
- Select Empty SharePoint Solution, fill in the URL, select Sandboxed
- Create a folder named
Resources
Step 2: Fill the Resources Folder
Add resource files to the Resources folder:
MuiSeries1.resx— language-neutral fallback (invariant)MuiSeries1.nl-NL.resx— DutchMuiSeries1.fr-FR.resx— FrenchMuiSeries1.en-US.resx— English
Use the correct culture-specific code between the resource name and .resx.
Step 3: Add Satellite Assemblies to the Package
When you build, you’ll find 3 language resource satellite assemblies in the bin folder.
To include them in the solution package:
- Select your solution package file → click Advanced at the bottom
- Click Add → select the DLL for each language (from the
Releasedirectory — never use Debug DLLs in production) - In the Location field, add the culture prefix: e.g.
en-US\YourAssembly.resources.dll
Repeat for each language (nl-NL, fr-FR, en-US in this example).
Important limitation: List Definitions, List Instances, and Feature titles/descriptions cannot use sandboxed resource files for MUI, because sandboxed resources are not stored in the 14-hive directories. To support MUI for those, you need a separate farm-level solution that deploys resource files to
{14hive}\Resources.
Step 4: Create the Sandboxed Web Part
Example: a restaurant sign-up form with three labels (restaurant name, score, rating) that need to display in the user’s language.
In the .ascx file: Leave the Text attribute of labels empty — do not use <%$Resources:...%> syntax. This causes a compile error in sandbox solutions: “The name ‘InitializeControl’ does not exist in the current context”.
In the code-behind: Set label text programmatically.
For resources deployed as part of the sandbox solution, use the generated resource class directly:
lblScore.Text = MuiSeries1.ScoreLabel;
For resources in the 14-hive (farm solution), use SPUtility.GetLocalizedString via a helper class:
public static class ResourceHelper
{
public static string GetString(string resourceFile, string key)
{
uint lcid = (uint)SPContext.Current.Web.Language;
return GetString(resourceFile, key, lcid);
}
public static string GetString(string resourceFile, string key, uint lcid)
{
return SPUtility.GetLocalizedString(
"$Resources:" + key,
resourceFile,
lcid);
}
}
Usage:
lblRestaurantName.Text = ResourceHelper.GetString("MuiSeries1", "RestaurantNameLabel");
This pattern works correctly in sandboxed solutions because SPUtility.GetLocalizedString is allowed in the sandbox.
Result
After deploying, label text automatically switches based on the user’s language profile (set via My Settings in the user menu). The web part also demonstrates multilingual dropdown values.
Next blog post will cover feature resource files — which can also be used in sandbox solutions 😊