在运行时设置ASP.NET母版页

时间:2020-03-05 18:40:31  来源:igfitidea点击:

我在一个需要能够支持两个或者多个外观且在运行时可更改的网站上工作。我希望能够使用CSS开关来处理更改,但是看起来我需要为每个设计使用不同的母版页。

那么,在运行时设置母版页的最佳方法是什么? Page.MasterPageFile只能在Page.OnPreInit事件中设置。看来解决方案是使我的所有页面都从处理PreInit事件的通用库继承,或者使用执行该操作的HttpModule。

有什么建议吗?

解决方案

回答

与其拥有两个不同的母版页,不如让一个母版来动态加载不同的用户控件和内容HTML文字,该怎么办?

回答

我之前已经做过一次,完全按照描述进行了(使所有页面都继承自带有OnPreInit事件的自定义页面)。另外,我在Global.asax.cs中有一个自定义Application_PreRequestHandlerExecute,用于设置Page.StyleSheetTheme来执行不需要其他母版页的图像/ css更改。

回答

处理PreInit并插入一行代码以加载正确的母版页非常容易。

this.Page.MasterPageFile = "~/default.master";

在没有令人信服的理由不走这条路的情况下,无论我们在何处使用PreInit,这都是我要做的。

回答

我很好奇是什么决定了页面的外观?用户是否单击按钮来更改主题?是否基于用于访问该网站的URL?

母版页支持后面的代码,因此我们可以在一个母版页中放入一些逻辑来决定应显示的内容。

我已经看到几个站点根据用户单击设置cookie(以更改字体大小或者页面宽度),然后根据这些cookie的值应用不同的CSS文件。如果没有cookie,则显示默认外观。

编辑:

如果我们只是想退出CSS,这里的另一个想法是将样式标签设置为在服务器上运行,并在运行时为其分配属性。再一次,这将需要使用单个母版页,并将代码放在母版页的代码后面,可能在PreInit事件处理程序中。

由于我从未实现过此解决方案,因此不确定整个<HEAD>标记是否必须在服务器上运行。

<html>
<head id="Head" runat="server">
<style id="StylePlaceholder" runat="server" type="text/css"></style>
</head>

回答

我感到你很痛苦。我搜索了大约一个小时(如果没有更多时间)来解决这个问题,但没有成功。当我们有数百个页面时,说"只要在每页上从PreInit调用它",不只是一个简单的答案。但是后来我意识到,与在每个页面上花费的时间相比,我在寻找解决方案上花费了更多的时间。

但是,我想基于Profile属性设置MasterPageFile,这样每页大约需要5行代码,这是可维护性的噩梦。无论如何,"不要重复自己",对吗?

因此,我在App_Code文件夹中的模块中创建了一个Extension方法,以使其更易于维护。

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

然后在每个页面的PreInit上,我都这样称呼:

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
        Me.SetMaster()
    End Sub