I am making some changes to a user control (.ascx file) in my ASP.NET 3.5 web application project in Visual Studio 2008. I noticed that the changes I was making in the markup were not being reflected in the designer file (a fairly well-known problem). I tried deleting the designer file and regenerating it using "Convert to Web Application." On doing so, I got this error:
Generation of designer file failed: Could not load type 'MyWebApplication.MyCustomExpressionBuilder' from assembly 'System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. (E:\MyPath\MyWebApplication\Web.config line 166)
The change I was making in the .ascx markup was to use a custom ExpressionBuilder
as the value of the Visible
and/or Enabled
properties of certain controls within my .ascx. This particular ExpressionBuilder
is successfully used elsewhere in the web application to return Boolean values to similar properties. For example:
<asp:TableRow runat="server" Visible="<%$ MyCustom: TheExpressionValue %>">
<%-- some TableCells and contents here --%>
</asp:TableRow>
The Web.config line noted in the error message is the add
tag in the following:
<system.web>
<compilation debug="true">
<!-- Skipping the 'assemblies' and 'buildProviders' areas -->
<expressionBuilders>
<add expressionPrefix="MyCustom" type="MyWebApplication.MyCustomExpressionBuilder" />
</expressionBuilders>
</compilation>
<!-- other stuff -->
</system.web>
The class MyCustomExpressionBuilder
is in the same web application project in a directory called Code
(not App_Code
, for whatever reason, and I'm not sure how much will break if I move the class file).
I can work around this issue if I have to by avoiding the custom ExpressionBuilder
in the control and adding some properties for the calling page to use instead, but that would not be ideal. Note that built-in expressions (like <%$ Resources: CommonResource, SomeTextString %>
) were already in the control and were working fine.
Here are some things I have tried:
ClassName
parameter to my <%@ Control %>
directive, as suggested here. No effect.<%@ Assembly Name="MyWebApplication" %>
. No effect.<%@ Import Namepace="MyWebApplication" %>
. No effect.<%@ Reference VirtualPath="~/Code/MyCustomExpressionBuilder.cs" %>
. No effect.Upgrading the project to a new Visual Studio version is not currently an option. As mentioned earlier, I would prefer not to move the custom ExpressionBuilder
class, since it is working at least from .aspx files. What else can I try?
I figured it out. The issue is that, for some reason, the compiler cannot find the assembly with the custom ExpressionBuilder
. What fixed the problem was to use a Partial Assembly Reference with slightly more information than just the class name and namespace in the add
tag:
<system.web>
<compilation debug="true">
<!-- Skipping the 'assemblies' and 'buildProviders' areas -->
<expressionBuilders>
<add expressionPrefix="MyCustom" type="MyWebApplication.MyCustomExpressionBuilder, MyWebApplication" />
</expressionBuilders>
</compilation>
<!-- other stuff -->
In other words, change the type
attribute to specify both the class name (with namespace) and the name of the assembly. Note that specifying any more additional information causes a different error (even the version number, and even if the version number is correct).
As to how I found out, a good tip for solving these problems is to enable logging as described here. For VS2008, you would use regedit
to:
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0
WebApplicationProjects
if it does not exist. Then, select it.Debug
if it does not exist. Then, select it.LogFile
. The value should be a path to which VS2008 will have write permissions (so, potentially not a file in the root of C:). Make sure to escape any backslashes, like C:\\PathICanWrite\\vslogfile.txt
.Enabled
, and set it to 1.LogFieldGeneratorFailures
, and set it to 1.When I looked at the log file, I was able to use the stack trace to determine that I had an assembly load problem, which now seems obvious. A message in the log gives a further tip to resolve assembly load issues:
WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
I found that I needed to restart the machine for the new registry setting to take effect. Then, additional assembly binding information was available in the log.