views:

645

answers:

4

C#, .NET 2.0

I have an ASP.NET website in a solution, with 2 other projects (used as library references). When I build (debug or release) in Visual Studio, everything works fine. However, building with MSBuild fails.

This build had been working (it's actually invoked via a nAnt task). The only thing that has changed is that I have a new user control whose Type I am referencing in my code behind.

The offending code is in my ASPX code behind. MessageAlert is the UserControl:

MessageAlert userControl = this.LoadControl("~/UserControls/MessageAlert.ascx") as MessageAlert;
        userControl.UserMessage = message;
        this.UserMessages.Controls.Add(userControl);

In order to get Visual Studio to recognize the type 'MessageAlert' I had to:

1) Set the ClassName="MessageAlert" in the @Control markup at the top of the user control (because using the auto-generated UserControls_MessageAlert wasn't working either)

2) Register the user control in the markup of my ASPX, using an @Register

3) Add a "using ASP" to the top of my code behind

After those steps, I could successfully reference the MessageAlert type in my codebehind from visual studio. But from MSBuild I get "The type or namespace name 'MessageAlert' could not be found (are you missing a using directive or an assembly reference?) "

The MSBuild execution is very simple - it points the the very same solution file and sets the configuration property to release.

It seems, based on the # of steps I had to go through to get Type references to MessageAlert in Visual Studio, that there is something missing in the MSBuild process. But what? Doesn't Visual Studio in fact invoke MSBuild behind the scenes?

Is there a better way to reference a UserControl type in the code behind of an ASPX?

EDIT: To clarify, the MessageAlert user control is not in the other referenced assemblies/projects. I mentioned them because, together with the website, the compose the Solution file, which is the same sln file being built by MS Build.

A: 

This seems to be a HintPath problem within your Solution. If you add your referenced assemblies to your project as linked project items (as well as project references), MSBuild will used the linked assemblies in preference to the HintPath and even AssemblyFolders.

An other way would be to add a key with any name to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio_YourVersion_\AssemblyFolders, and set its (Default) value of type REG_SZ to the path with your assemblies.

zoidbeck
A: 

Are you using this in a web site "project"? If so, they're not really meant to build, per se. This might also be responsible for the "UserControls_MessageAlert" you were seeing.

John Saunders
+1  A: 

I also had this problem exactly as you described above.

I was at a loss as to why this was and as a final mesure, decided to try the following with success.

Change the class name of the user control - the actual class name not the class name in the aspx file.

so in your example change the class name to MessageAlert (from UserControls_MessageAlert) also change this in the inherits in the aspx

Hope this helps someone

Thanks for the tip. I ended up doing some refactoring anyway and resolved this problem through different means (no longer trying to use a UserControls_ class outside of its internal context), so can't verify if this would've fixed the problem for me. But thanks!
Matt
A: 

Try removing the "using ASP" section from your page and make sure the "ClassName" property of the @Control directive actually matches the name of the class. We had the ClassName value set to "FilterElement" while the actual class name was "Controls_FilterElement".

So, in summary:

  • Verify your class name in the .ascx.vb and the inherits property of the @Control directive on the .ascx. e.g. Inherits="FilterElement"
  • Add the "ClassName" property to the @Control directive with the same value, e.g. ClassName="FilterElement"
  • On the referring page / control add the "Reference" element. e.g.

    <%@ Reference Control="~/Controls/FilterElement.ascx" %>

  • In the code behind, refer to the class directly. Do not use the ASP namespace (this seems to be what causes msbuild the difficulty). e.g. (in VB)

    Dim ctrlElement As FilterElement = CType(LoadControl("~/controls/filterelement.ascx"), FilterElement)

Zarigani