Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedded resources in assembly containing culture name in filename will not load

I'm trying to embed some email templates in a class library. This works fine, until I use a filename containing a culture-name with the following notation: templatename.nl-NL.cshtml The resource does not seem to be available.

Example code:

namespace ManifestResources
 {
    class Program
    {
        static void Main(string[] args)
        {
            var assembly = Assembly.GetExecutingAssembly();

            // Works fine
            var mailTemplate = assembly.GetManifestResourceStream("ManifestResources.mailtemplate.cshtml");

            // Not ok, localized mail template is null
            var localizedMailTemplate = assembly.GetManifestResourceStream("ManifestResources.mailtemplate.nl-NL.cshtml");
        }
    }
}

Templates both have build action set to 'EmbeddedResource'.

Obvious solution is to use a different notation, but I like this notation. Anyone has a solution for this problem?

like image 614
Robin van der Knaap Avatar asked Aug 07 '13 16:08

Robin van der Knaap


1 Answers

I hope I am not late with answer.

When you add templatename.nl-NL.cshtml as embedded resource, it lands in satellite assembly with resources for nl-NL language.

If you go to bin/debug directory, you'll find nl-NL folder with NAMESPACE.resources.dll in it.

satellite assembly directory

satellite assembly name

If you decompile this assembly, you'll find templatename.cshtml file inside.

enter image description here

To read it, you have to get this assembly and read resource from it.

To get it, you have to execute this code:

var mainAssembly = AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "ConsoleApp2");

ConsoleApp2 was namespace where I had all my resources. Code above will get assembly only if it is already loaded. I assumed it is.

Then you have to get satellite assembly. This is main difference between standard file reading from embedded resource:

var satelliteAssembly = mainAssembly.GetSatelliteAssembly(CultureInfo.CreateSpecificCulture("nl-NL"));

And then we have standard method to read resource file:

var resourceName = "ConsoleApp2.templatename.cshtml";

using (Stream stream = satelliteAssembly.GetManifestResourceStream(resourceName))
    using (StreamReader reader = new StreamReader(stream))
    {
        string result = reader.ReadToEnd(); // nl-NL template
    }

Example project file here.

like image 115
LukLed Avatar answered Sep 19 '22 13:09

LukLed