No se pudo cargar el tipo de 'ASP.XXX' al hacer referencia a una página maestra precompilada

StackOverflow https://stackoverflow.com/questions/5807209

Pregunta

Estoy intentando precompilar algunas páginas maestras (no actualizables) para compartirlas en múltiples aplicaciones. El proyecto que estoy precompilado es un sitio web. El proyecto que hace referencia a los ensamblajes precompilados es una aplicación web. Sin embargo, estoy obteniendo un tipo de no poder cargar 'ASP.XXX_Master' cada vez que intento hacer referencia a la página maestra desde el cliente.

<%@ Master Language="C#" Inherits="ASP.sitebase_master" %>

Mi página maestra precompilada se ve así.

<%@ Master Language="C#" ClientIDMode="Static" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org  /TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="AspNetHead" runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />   
    <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=7" /><![endif]-->
    <asp:ContentPlaceHolder ID="MetaContent" runat="server" />
    <title>Web Portal</title>   
    <link href="/media/css/style.css" rel="stylesheet" type="text/css" />
    <link href="/media/js/plugins/colorbox/colorbox.css" rel="stylesheet" type="text/css" />
    <asp:ContentPlaceHolder ID="StyleContent" runat="server" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js" type="text/javascript" language="javascript"></script>
    <script src="/media/js/plugins/colorbox/jquery.colorbox-min.js" type="text/javascript" language="javascript"></script>
    <script src="/media/js/plugins/filestyle/jquery.filestyle.min.js" type="text/javascript" language="javascript"></script>
    <script src="/media/js/portal.master.js" type="text/javascript" language="javascript"></script>
    <script language="javascript" type="text/javascript">
        PORTAL.debug.init();
        PORTAL.init();
    </script>
    <asp:ContentPlaceHolder ID="ScriptContent" runat="server" />
</head>
<body>
    <div id="hld">  
        <div class="wrapper">
            <form id="AspNetForm" runat="server">
                <asp:ContentPlaceHolder ID="BodyContent" runat="server" />  
            </form>
            <asp:ContentPlaceHolder ID="FooterContent" runat="server" />
        </div>
    </div>
</body>

Estoy perplejo. No tengo idea de por qué el tipo no está resuelto. ¿Alguien tiene sugerencias? Ambos proyectos (sitio web precompilado y aplicación web del cliente) están creados para ASP.NET 4.0.

EDITAR: Aquí está la lista de dependencias del ensamblaje precompilado. No hay referencias de terceros.

Mscorlib, System, System.Web

Udpate 1

Bueno, la solución rápida a este problema es especificar la ruta completa a la página maestra.

<%@ Master Language="C#" Inherits="ASP.sitebase_master, App_Web_sitebase.master.cdcab7d2" %>

Después de hacer eso, recibo el siguiente error:

Se produjo un error mientras intentaba cargar los recursos de cadena (FindResource falló con el error -2147023083).

Después de investigar un poco, esto parece estar relacionado con la forma en que el marcado HTML se analiza dentro de la página maestra. No estoy del todo seguro todavía. No he cavado mucho más profundo. En general, no puedo creer que esta sea la forma recomendada de compartir los controles, ya que es absolutamente, muy idiota.

Actualización 2

No pude hacer nada de valor de esto. Parece estar odiando las etiquetas de "script" en la sección principal, pero no sé por qué. La página maestra funciona muy bien con un solo script que incluya. Tan pronto como empiezo a agregar más, sigo recibiendo ese error. Después de perder un día completo sobre esto, terminé enviando un informe de error a Microsoft. Si alguien quiere golpearlo, por favor hazlo.

Actualización 3

Pasé unos días más depurando esto después de ninguna respuesta de la EM. Aquí están mis hallazgos. Inicialmente pensé que el código generado por el proveedor de Codedom está buscando un recurso .NET que de alguna manera no se incrustó en el ensamblaje cuando se publicó. Estaba equivocado. Después de alguna investigación, parece que lo que está sucediendo es después de que la página maestra alcanza un cierto tamaño, una parte se almacena en la tabla de recursos en la sección Directorios de datos de PE del ensamblaje. De hecho, después de mirar el ensamblaje generado en PE Resource Viewer, pude confirmar esto al encontrar todo mi script que incluye en la tabla de recursos. Ahora, aquí está el problema real. Lo que está sucediendo es que el proveedor de Codedom genera una llamada a Win32 FindResource para extraer ese recurso de la tabla de recursos. Sin embargo, FindResource no funciona en ensamblajes en la memoria, solo en el disco. Entonces falla con la excepción anterior. Me estoy acercando, pero aún no hay solución.

¿Fue útil?

Solución

Finalmente tengo una solución. No es bonito, pero resuelve el problema. Aparentemente, el uso de LoadControl para precompilarse MasterPages, carga todos los recursos que FindResource no puede encontrar lo contrario. Entonces, aquí está todo lo que hice para que esto funcionara.

En mi aplicación de cliente, creé una página maestra ficticia (es decir, dummy.master) que hace referencia a mi página maestra precompilada como así:

<%@ Master Language="C#" Inherits="ASP.sitebase_master, App_Web_sitebase.master.cdcab7d2" %>

Ahora, cualquier página .aspx que hace referencia a Dummy.Master necesita precargar el tipo de MasterPage precompilado así:

        protected override void OnPreInit(EventArgs e)
        {
            ASP.sitebase_master mp = (ASP.sitebase_master)Page.LoadControl(typeof(ASP.sitebase_master), null);

            base.OnPreInit(e);
        }

No sé por qué funciona esto, pero lo hace. Este código debe ejecutarse antes de que se resuelva la MasterPage, por lo que preinit funcionó muy bien. Después de mirar el código .NET durante unos segundos en reflector, parece que LoadControl en realidad hace un vudú de compilación de ensamblaje cuando intenta cargar cierto tipo de control. Entonces, tal vez algo esté allí cargue esa sección de datos de recursos PE. El mejor lugar para ponerlo sería en la clase base, supongo que todas las páginas podrían heredar. Además, cada control cargado (página maestra en este caso) debe almacenarse en caché. Aquí hay un buen artículo que explica exactamente eso.

Esperemos que esto ayude a alguien tanto como me ayudó. Fue un parto de espectáculos bastante grande para mí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top