About embedded & external resource files

5 בFebruary 2013

tags: ,
4 comments

About embedded & external resource files

ASP.NET logo

Recently I was asked by a colleague of mine to help him with a problem.
He had tried numerous times to work with resource files on a web project
and got many errors until he had moved the files build action from content
to embedded resource.

 

What’s the difference?

Embedded resources are files that are put inside the compiled assembly when compiling it.
However, when a resource file build action is content, only the .designer.cs file that
comes with it is compiled (you can see that its build action is compile) and the .resx file
is copied as is when publishing the application.

However, when adding resource (.resx) file into another application or class library, its
default build action will be Embedded Resource instead of Content . The .designer.cs
file will have the same build action, Compile (as every code file).

You may see it from both screenshots below: 
Embedded resource property grid  Content .resx file property grid

Please note another two different values on the CustomTool property. The CustomTool
is the component in charge of creating the code in the .designer.cs file. This property is
overlooked.  The Embedded Resource has ResXFileCodeGenerator custom tool while
the other one has GlobalResourceproxyGenerator custom tool.

And what is the difference between the two custom tools?

The main difference is in the .designer.cs . This file contains class with static properties
where each property uses ResourceManager.GetString method in its getter, to return
the value.

Here’s the code (on both generated files)

internal static string MyResource {

    get {

        return ResourceManager.GetString("MyResource", resourceCulture);

    }

}

However, the ResourceManager property is created differently. Let’s have a look on how it

is created in the with the file generated with ResXFileCodeGenerator custom tool

(Embedded resource).

 

internal static global::System.Resources.ResourceManager ResourceManager {

    get {

        if (object.ReferenceEquals(resourceMan, null)) {

            global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MyClassLibrary.ClassLibraryResource", typeof(ClassLibraryResource).Assembly);

            resourceMan = temp;

        }

        return resourceMan;

    }

}

And the one generated by GlobalResourceproxyGenerator  (in use in web applications,

Content buld action).

internal static global::System.Resources.ResourceManager ResourceManager {

    get {

        if (object.ReferenceEquals(resourceMan, null)) {

            global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Resources.MyWebResource", global::System.Reflection.Assembly.Load("App_GlobalResources"));

            resourceMan = temp;

        }

        return resourceMan;

    }

}

The difference is the Assembly of the resources. While the first code snippet goes to

the assembly holds the class inside the .designer.cs file (which is the class library

compiled DLL), the web application code loads assembly by reflection.

And what is the assembly it loads?

Well, the aspnet  compiler generates assemblies from all markup code, where each

folder is compiled into different assembly. Therefore the actual resources are

located in different assembly than the code behind (which compiled by the 
aspnet compiler as al content files)  and therefore published as is to the target

server where our web application runs.

 

Summary:

Although looks the same and has very similar code, when having resource file

on ASP.NET applicationis by default not embedded resource.

To have the resource outside of the ASP.NET application’s

assembly we must have the right custom tool chosen.

Shout it

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

4 comments

  1. Vijay7 בApril 2015 ב 10:24

    What is ideal properties for .resx while publishing to production server. I am using Global resource with BuildAction as Embeded Resource…after publishing it is giving error like resource does not find key….Please help me out this problem…..you can contact me at “vijay@nlogixsolutions.com”

    Reply
    1. Ran Wahle
      Ran Wahle7 בApril 2015 ב 10:45

      Well Vijay – ineed some more details.

      Are you trying to read your resources from the markup? because if so, the resource class is internal and won’t be read from the markup.
      What is the exact error message you get?

      Reply
  2. Sara14 בMarch 2017 ב 2:12

    You are forgetting about some of the other custom tools like PublicResXFileCodeGenerator. That allows you to make a resource public. All you do is change the custom tool, mark the resource as embedded and build the project. The resource file will then be automatically changed to Public and can be used as such in your project.

    Reply
    1. Ran Wahle
      Ran Wahle21 בMarch 2017 ב 9:48

      Thanks for your comment Sara, Actually the purpose of this post wasn’t to present all resource generators, just to explain why you don’t need to publish .resx files.

      You will need to make your resources public if they are used outside of your assembly, such as markup files, and in that case your are absolutely right.

      Reply