Вопрос

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:

  1. Just rebuilding the project. The designer file does not load, and I get lots of build errors in the code-behind due to missing properties.
  2. Just changing the control markup, saving, and changing the control back (before I tried deleting the designer file), making sure that I did not have the designer file open. This process just failed silently.
  3. Adding the ClassName parameter to my <%@ Control %> directive, as suggested here. No effect.
  4. Adding <%@ Assembly Name="MyWebApplication" %>. No effect.
  5. Adding <%@ Import Namepace="MyWebApplication" %>. No effect.
  6. Adding <%@ Reference VirtualPath="~/Code/MyCustomExpressionBuilder.cs" %>. No effect.
  7. Closing and restarting Visual Studio. On the first attempt to run "Convert to Web Application" on the ascx, at least I got a different error: "Exception of type 'System.Exception' was thrown." After attempting to rebuild the project and getting all the errors (see #1 above), "Convert to Web Application" produces the same "Generation of designer file failed" error message as before.

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:

  1. Go to HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0
  2. Create a new key named WebApplicationProjects if it does not exist. Then, select it.
  3. Create a new key named Debug if it does not exist. Then, select it.
  4. Add a new string called 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.
  5. Add a new DWORD called Enabled, and set it to 1.
  6. Add a new DWORD called LogFieldGeneratorFailures, and set it to 1.
  7. Restart VS2008.

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top