Embedded Resources difference between VB.NET and C# projects

While I am developing a custom web control to extend the default validation summary I used some images within this control. One of the nice features and solutions came with ASP.NET 2.0 to address this problem is using web resources. So I embedded these images in my custom control assembly and used the Page.ClientScript.GetWebResourceUrl to resolve their URL's.

To do this task correctly you need to do 2 simple steps:

  1. First, you need to select whatever file you want to embed in your assembly and then set the Build Action property from its properties to Embed this is straight forward as saying 1, 2, 3.
  2. The second this we need to do is referencing that embedded resource so it could be retrieved as a web resources.This could be accomplished by adding WebResource attributes in the Assembly.info file.


    In general to do this all we need is to add the web resource attribute like

    <Assembly: System.Web.UI.WebResource("EmbeddedResourcesVB.Sunset.jpg", "image/jpg")>  the WebResource takes two parameters, the first one is the resource full name which following this convention: (Rootnamespace).(SubNameSapce).(Filename).(Extension) and the second parameter is the MIEM file type of the resource

So what's wrong?

This looks very simple but why all problems occurred? What is the error prone thing which make all these posts and articles on the web!! To identify this we can say there is some issue regarding the way that VB.NET projects and C# projects being organized. Is that true? Yes that's true!!

To figure out this issue I created simple solution conations a VB.NET project and a C# project. and add an image to each of them as our embedded resource. I changed the Root Namespace property for each project to make it clear that the assembly name has nothing to do with WebResource name. By default the Root Namespace == assembly name but in some certain scenarios you need to change that so by choosing the project properties you can change the assembly name property and the RootNamespace property.

After building our solution let's have a closer look to the embedded resources after being compiled into assembly. So let's open EmbResVB.dll and EmbResCSharp.dll using Reflector. If you take a quick look to the image below you can note that the Sunset.jpg image resource name differs from the Vb.Net assembly to the C# one.

   

But we said that the resource name should follow this convention: (RootNameSpace).(SubNameSapce).(Filename).(Extension) so what's happens??!!
Here's what happen: in the C# projects if you add a new class to your solution you will find that the IDE put's this file in a namespace regarding to the solution folders hierarchy. But in VB.NET projects this is not occur. Let's take the ImagesUrl class as example, this class which exists's under the images folder in our testing C# and VB.NET projects but it will look like this by default in C#:

using System;
using System.Collections.Generic;
using System.Text;

namespace EmbeddedResourcesCSharp.Images
{
   
public class ImagesURL
   
{


   
}
}

 

while in the VB.NET project it will be added to the root namespace by default:

 

Public Class ImagesUrl

   
Sub New()

Technorati Tags: asp.net,embbede resources,.Net



   
End Sub

End Class

C# is doing this because of the VC# wizards which work in the background when you add new items to your project. Here's an article for one of the VS team descriping this issue http://blogs.msdn.com/joen/archive/2004/03/15/90002.aspx.

Anyway it seems that C# IDE is handling the other files like our image in the same way. So our Sunset.jpg image have been listed under the images namespace which actually it's parent folder name. But in the VB.NET project Sunset.jpg is being added to the root namespace never mind in any sub folder it exists.

Ok, that's it, the reason of all the misunderstanding. Many VB.NET developers reading posts or articles about embedded resources written in C# and they didn't notice the different in embedded resources names between the VB.NET and C# projects.

The result

In a C# project embedded resources names follows this convention (RootNampeSpace).(Path).(FileName).(Extension) where Path is the folders path in which this resource exist Root/Folder/SubFolder/.../ResourceFile .In A VB.NET project embedded resources names follows this convention (RootNampeSpace).(FileName).(Extension) and the resource path does not affect its name.

 

Hope that help. Happy asp.net

Huthaifa

   

11 Comments

  • So you are talking about Web application project(WAP), What about website project (WSP) ? There is no available build action for the file , so how we can tell MsBuild to Embed the file in that case ?

    Thanks

  • ooops! When I wrote this post I never take in mind WSP case. As you know web site projects using a different compile model than the WAP and it has multiple options, I rarely used them and I still using WAP's anyway theirs a good article describing WSP compilation
    http://www.west-wind.com/presentations/AspNetCompilation/AspNetCompilation.asp
    I will google this issue to see if their is any information about it

  • For website project , you just need to decorate your control with System.Web.UI.WebResource attribute , so for examlpe if you want to embed image in the control assembly , you just need to decorate your control class with this attribute :

    [assembly: System.Web.UI.WebResource("myImage.gif", "img/gif")]

    I found a nice article ,take a look
    http://aspalliance.com/726

  • Huthaifa, you are spot on. I had a server control with an embedded java script file that I was converting from C# to VB. The control worked in C# but not VB. I used Assembly.GetManifestResourceNames() to check on the name of the embedded resource and noticed that it was missing the subfolder. I thought I was doing something wrong or some setting was missing or incorrect. Then I saw your post, which (to paraphrase Dr Stangelove) made me stop worrying and learn to love VB. Thanks much

  • The issue regarding the assembly path of the embedded resource really did it for me. I was trying to solve it in vb and all samples where in c# and I never understood why my tests failed. Now it works. Thanks a million

  • rp8ps5 Thanks a lot for the blog article.Really looking forward to read more. Fantastic.

  • 1IJseC Appreciate you sharing, great article.Really looking forward to read more. Great.

  • 9a3CE0 Looking forward to reading more. Great post.Really looking forward to read more. Awesome.

  • BIG THANKS, I spent 3 long days trying to figure this out. I am just getting up to speed on .net and this is the only article I found that explained it so clearly!

  • Very nice blog post. I certainly appreciate this website. Stick with it!

  • I'm gone to convey my little brother, that he should also go to see this blog on regular basis to obtain updated from latest information.

Comments have been disabled for this content.