Login.aspx não é WebControl!

Janeiro 20, 2007 at 11:40 am 1 comentário

Estes dias tive que fazer uns testes simples, criando uma página Default.aspx e uma página Login.aspx. Coloquei meu código, compilei e rodei a aplicação direto do Visual Studio. A execução foi como esperada, tudo certo.
Então ok, era hora de gerar uma publicação. Cliquei com o botão direito na aplicação web, Publish Web Site, publiquei e fui efetuar o teste final. Opa! Erro!

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: CS0030: Cannot convert type ‘ASP.login_aspx’ to ‘System.Web.UI.WebControls.Login’
Source Error:

Line 112:        public login_aspx() {
Line 113:            string[] dependencies;
Line 114:            ((Login)(this)).AppRelativeVirtualPath = "~/Login.aspx";
Line 115:            if ((global::ASP.login_aspx.@__initialized == false)) {
Line 116:                dependencies = new string[1];

Source File: c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\publishtest\43f5e5ee\53e358e4\App_Web_login.aspx.cdcab7d2.cji1wrof.0.cs    Line: 114

Fiquei um pouco surpreso com este erro, já que minha página se chamava Login.aspx e consequentemente herdava a classe chamada Login.

Pelo visto, na hora da compilação, o cast apresentado como na linha 114  interpreta que a classe Login é a do namespace System.Web.UI.WebControls, e não a minha página.

Aí vem outra dúvida: Por que debugando pelo Visual Studio executa corretamente e publicando não?

Analisando os códigos gerados, existe um grande diferença:

Código gerado em modo debug:
((System.Web.UI.Page)(this)).AppRelativeVirtualPath = “~/Login.aspx”

Código gerado depois de publicar o site:
((Login)(this)).AppRelativeVirtualPath = “~/Login.aspx”

Ok, então vamos voltar para a publicação.

Gerei esta publicação com as opções “Allow this precompiled site to be updatable” (1) e “Use fixed naming and single page assemblies” (2) marcadas. O “problema” está na primeira opção.

Quando geramos o site com a opção de permitir que o site seja atualizável, estamos dizendo ao compilador do asp.net para manter o conteúdo do aspx no próprio aspx e o code-behind em um assembly para esta página. Nesta opção, são gerados N assemblies, dependendo do número de páginas da sua aplicação.

Antes de continuarmos com o nosso problema, para demonstrar melhor o que acontece, vou explicar como é a compilação de um site updatable e exemplificar com um problema.

Então, utilizando a opção (1) na publicação, quando a página e o code-behind são compilados?

Nesta opção, apenas o código em code-behind é compilado antes da publicação. Isso quer dizer que as classes geradas pelo .aspx (não code-behind) são compiladas quando uma requisição é feita para algum arquivo no diretório. Então vamos analisar o segundo exemplo, fornecido por Fritz Onion:

myUserControl.ascx

<%@ Control Language=”C#” AutoEventWireup=”true” CodeFile=”myUserControl.ascx.cs” Inherits=”myUserControl” %>


<script runat=”server”>
public string Color
{
get { return (string)ViewState[“color”] ?? “white” }
set { ViewState[“color”] = value; }
}

protected override void OnLoad(EventArgs e)
{
_mainPanel.BackColor = System.Drawing.Color.FromName(Color);
base.OnLoad(e);
}
</script>

<asp:Panel runat=”server” ID=”_mainPanel”>
<h2>Some text</h2> Other text
</asp:Panel>

TestControl.aspx.cs

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”TestControl.aspx.cs” Inherits=”TestControl” %>

<%@ Register Src=”myUserControl.ascx” TagName=”MyUserControl” TagPrefix=”uc1″ %>

<!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=”Head1″ runat=”server”>
<title>Untitled Page</title>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>
<uc1:MyUserControl id=”MyUserControl1″ runat=”server”>
</uc1:MyUserControl></div>
</form>
</body>
</html>

TestControl.aspx.cs

using System;
using System.Web.UI;

public partial class TestControl : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
MyUserControl1.Color = “purple”
}
}

Então segundo o que foi explicado sobre compilação de “updatable site”, o código em code-behind é compilado antes da publicação, e os códigos em aspx/ascx são compilados quando alguma requisição é realizada.

Aqui está o problema: observe que o código do control myUserControl.ascx não está em Code-Behind, o que indisponibiliza a propriedade Color para a classe em TestControl.aspx.cs no momento em que esta classe é compilada.

Dito isso, agora vamos voltar ao nosso problema.
Quando executamos pelo Visual Studio, a compilação do aspx e do code-behind são feitas no mesmo momento. Aqui é possível então associar que a classe Login ao namespace System.Web.UI.Page. Sabemos no mesmo momento quem é (e o que é) a classe-pai do nosso aspx. Quando publicamos o site como updatable, o código gerado pelo aspx sabe somente qual o nome da classe que foi herdada, sem saber o que é esta classe, ou de onde veio. Isso faz com que a diferença nas linhas abaixo exista:

Código gerado em modo debug:
((System.Web.UI.Page)(this)).AppRelativeVirtualPath = “~/Login.aspx”

Código gerado depois de publicar o site:
((Login)(this)).AppRelativeVirtualPath = “~/Login.aspx”

Conclusão
Esse problema todo é conflito de namespace, e a única solução para driblarmos isso, utilizando o site como updatable, é alterar o nome da classe 🙂

Abraços!

Anúncios

Entry filed under: .NET.

Defend Your Code with Top Ten Security Tips Every Developer Must Know Orcas Web Designer

1 Comentário Add your own

  • 1. Paulo  |  Janeiro 25, 2008 às 12:30 pm

    Muito claro e útil o post.
    Parabéns!

    Responder

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


Calendário

Janeiro 2007
S T Q Q S S D
« Dez   Mar »
1234567
891011121314
15161718192021
22232425262728
293031  

Most Recent Posts


%d bloggers like this: