Monday, January 22, 2007

Fixing ASP.NET error BC30456

Ever got error BC30456?

Server Error in ... Application.
--------------------------------------------------------------------------------
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: BC30456: 'MasterPageFile' is not a member of 'ASP.area_areamasterpage_master'.
Source Error:
Line 1: <%@ master language="VB" inherits="userpage_UserMasterPage, App_Web_oa_obube" masterpagefile="~/MasterPage.master" %>
Line 2:
Line 3:
Source File: ...AreaMasterPage.master Line: 1


The symtom is that pages run fine as long as being executed with dynamic compilation-in-place, but fails when running after being precompiled.

The fundamental problem is a collision of class names. In the same folder, two classes can't have exactly the same name. So, either of the classes would have to be renamed so that no two instances of classes exists with the same names.

Let's go back to definitions a bit though. A class "exists" here in the sense that we have a codebehind file with a line saying Partial Class userpage_UserMasterPage where userpage_UserMasterPage is in fact the class name.
This name is also replicated in the aspx file. As usual, the aspx and codebehind class names must match. This gives us a set of truths to maintain:
(1) define class name in codebehind file
(2) define class name in aspx file
(3) class name in aspx and codebehind file name must match
(4) class name must be unique (within application/namespace presumably)
Error BC30456 will likely occur if 1,2,3 is true but 4 is not true.

One simple cause of the error is that a page, including its codebehind file, has been copied to a new file, renamed and edited, but the name has not been changed. The result would be that the precompiled site compiles correctly but the page cannot be visited if there is an internal duplicate. It is therefore tough to spot these error until deployment compilation happens, as it doesn't show as a warning.

In a particular case I experienced here, the error occured in the case where there was an unused nested master page with the same class name, e.g.:

1. Root masterpage
2. Child masterpage of root masterpage (e.g. child of page in (1)).
3. Copy of child masterpage of root masterpage (e.g. copy of page in (2)).

The resolution was to rename the class name in the copied page. Although the copied page was not in use, the child page in use (e.g. in point 2) could not be visited, and as a result, all aspx pages using the child masterpage could not be visited, which were several!

Resolution: fixing one of the master pages (preferably the unused, to reduce the need for slowing-down recompilation on-the-fly) by
(1) opening two files of the master page: the codebehind and aspx
(2) devising a new unique name, e.g. by appending a suffix to the current name
(3) renaming class in codebehind
(4) renaming class in aspx
(5) saving
(6) recompiling

By the way, it is fine if there are similar class names but in different folders of the application.

No comments: