Configurando uma página mestra ASP.NET em tempo de execução
-
08-06-2019 - |
Pergunta
Estou trabalhando em um site que precisa suportar dois ou mais looks, alteráveis em tempo de execução.Eu esperava poder lidar com a mudança com uma opção CSS, mas parece que precisarei usar uma masterpage diferente para cada design.
Então, qual é a melhor maneira de definir a masterpage em tempo de execução?Page.MasterPageFile só pode ser definido no evento Page.OnPreInit.Parece que as soluções são fazer com que todas as minhas páginas herdem de uma base comum que lida com o evento PreInit ou usar um HttpModule que faça isso.
Algum conselho?
Solução
Já fiz isso uma vez, fiz exatamente o que você descreveu (fez com que todas as páginas herdassem de uma página personalizada com um evento OnPreInit).Além disso, eu tinha um Application_PreRequestHandlerExecute personalizado em meu Global.asax.cs para configurar Page.StyleSheetTheme para fazer alterações de imagem/css que não exigiam uma página mestra diferente.
Outras dicas
Em vez de duas páginas mestras diferentes, que tal ter uma mestra que carregue dinamicamente diferentes controles de usuário e literais HTML de conteúdo?
Eu sinto sua dor.Procurei por cerca de uma hora (se não mais) um problema relacionado a isso, sem sucesso.Não é apenas uma resposta direta dizer "basta chamá-lo do PreInit em cada página" quando você tem centenas de páginas.Mas então percebi que estava gastando mais tempo procurando uma solução do que seria necessário apenas fazendo isso em cada página.
No entanto, eu queria definir o MasterPageFile com base em uma propriedade Profile, de modo que teria cerca de 5 linhas de código em cada página, um pesadelo de manutenção.E de qualquer forma, “não se repita”, certo?
Então criei um método Extension em um módulo na pasta App_Code para tornar isso mais fácil e de fácil manutenção.
Public Module WebFunctions
<System.Runtime.CompilerServices.Extension()> _
Public Sub SetMaster(ByVal page As Page)
Dim pb As ProfileCommon = DirectCast(HttpContext.Current.Profile, ProfileCommon)
If pb IsNot Nothing Then
page.MasterPageFile = pb.MasterPage
End If
End Sub
End Module
E então, no PreInit de cada página, eu apenas chamo isto:
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Me.SetMaster()
End Sub
É fácil manipular o PreInit e inserir a única linha de código necessária para carregar a página mestra adequada.
this.Page.MasterPageFile = "~/default.master";
Na ausência de algum motivo convincente para não seguir esse caminho, é isso que eu faria, independentemente de onde você lida com o PreInit.
Estou curioso para saber o que decide a aparência da página.É o usuário clicando em um botão para mudar o tema?É baseado no URL usado para acessar o site?
Code Behind é suportado em páginas mestras, então você pode colocar alguma lógica em sua página mestra para decidir o que deve ser exibido.
Já vi vários sites definirem cookies com base nos cliques do usuário (para alterar o tamanho da fonte ou a largura da página) e, em seguida, aplicar diferentes arquivos CSS com base no valor desses cookies.Se nenhum cookie estiver presente, exiba uma aparência padrão.
EDITAR:
Outro pensamento aqui, se você está simplesmente tentando trocar o CSS, é definir sua tag de estilo para ser executada no servidor e atribuir propriedades a ela em tempo de execução.Mais uma vez, isso exigiria o uso de uma única página mestra e a colocação do código no code-behind da página mestra, provavelmente no manipulador de eventos PreInit.
Como nunca implementei esta solução, não tenho certeza se toda a tag <HEAD> deve ser executada no servidor ou não.
<html>
<head id="Head" runat="server">
<style id="StylePlaceholder" runat="server" type="text/css"></style>
</head>
Herde todas as suas páginas de uma classe base como
public class PageBase : System.Web.UI.Page
{
public PageBase()
{
this.PreInit += new EventHandler(PageBase_PreInit);
}
void PageBase_PreInit(object sender, EventArgs e)
{
this.MasterPageFile = "~/MyMasterPage.Master";
}
}