A recent ASP. Net project may encounter a compilation error from time to time, prompting that the ascx class of a control does not exist, but the control is clearly on the same website. Errors sometimes occur suddenly, and once an error occurs, it cannot be eliminated after multiple compilation. Because the company uses script compilation instead of msbuild or Visual Studio for direct compilation. In fact, compiling with Visual Studio has never been a mistake. Use procexp to check what was actually executed during build:
Aspnet_compiler.exe-D-V/-P <source webroot> <target webroot>
This command is used. Is there a bug in the compiler? Then I will find that aspnet_compiler.exehas used csc.exe (C # compiler ):
"C: \ WINDOWS \ Microsoft. net \ framework \ v2.0.50727 \ csc.exe "/noconfig/fullpaths @" C: \ WINDOWS \ Microsoft. net \ framework \ v2.0.50727 \ temporary ASP. net files \ Root \ 1c85b622 \ f7798d18 \ mz_xtoba.20.line"
Go to the temporary ASP. NET files \ Root \ 1c85b622 \ f7798d18 directory, and find many files such as. program line,. Err,. Out,. compiled, and many other. CS files! The original. CS files on web pages or appcode are reorganized and grouped here: app_code.n.cs; app_web _ <XXX>. N. CS; (n = 0 ~...). If there are many webpages, there will be multiple groups of app_web _ <XXX>. N. CS. The compiler will compile n CS files in a group, and the next CS compilation will reference the DLL generated by the previous compilation (in. cmdline ):
/T: Library/utf8output/R: "system. web. services. DLL "/R:" app_global.asax.dll "/R:" app_web_rydiwb8f.dll "/out:" app_web_bl8pd2er.dll "app_web_bl8pd2er.9.cs parameters (some paths and parameters have been omitted. App_web_bl8pd2er.dll references the app_web_rydiwb8f.dll generated by the previous CS group)
But how can we determine the file group? Which files should be placed in the previous group, and where should the files be placed behind? In. aspx. XXX. compiled or. ascx. XXX. Compiled, we found the information on which the file depends:
<? XML version = "1.0" encoding = "UTF-8"?>
<Preserve resulttype = "3" virtualpath = "/result. aspx "hash =" 84d987223 "filehash =" a23fecda9fe4d6d8 "Flags =" 110000 "assembly =" app_web_wt3qqawy "type =" ASP. result_aspx ">
<Filedeps>
<Filedep name = "/controls/control1.ascx"/>
<Filedep name = "/controls/control1.ascx. cs"/>
<Filedep name = "/result. aspx"/>
<Filedep name = "/result. aspx. cs"/>
</Filedeps>
</Preserve>
Therefore, the compiler maintains such dependencies in the memory and generates a tree to determine the sequence of file groups. However, the. compiled file is generated only after the page is successfully compiled.
After understanding this, let's look at the problem of the project: the original result. aspx. CS dynamically created control2:
Control2 CTRL = (control2) page. loadcontrol ("controls \ control2.ascx ");
Page. placeholder. Controls. Add (CTRL );
However, this dependency cannot be found in the. compiled file! Therefore, the compiler does not know to divide control2.ascx into the previous Group of result. aspx. In this way, sometimes compilation can be passed (just divided into peer groups, the above. compiled file is what happens when the compilation is successful) and sometimes the strange problem occurs. Solution: register the control2 control on the result. ASPX page: <% @ register tagprefix = "uc1" tagname = "control2" src = "controls \ control2.ascx" %>
Even if the ASPX page does not directly reference the control, add this line to let the compiler know that the page references the control. The file dependency and the. compiled file use this information, and the compiler does not read the references in the. CS file.