Установка главной страницы ASP.NET во время выполнения

Я работаю над сайтом, который должен поддерживать два или более внешнего вида с возможностью изменения во время выполнения. Я надеялся, что смогу обработать изменение с помощью переключателя CSS, но похоже, что мне нужно будет использовать разные мастер-страницы для каждого дизайна.

Итак, как лучше всего установить главную страницу во время выполнения? Page.MasterPageFile можно установить только в событии Page.OnPreInit. Похоже, решения заключаются в том, чтобы все мои страницы унаследовали от общей базы, которая обрабатывает событие PreInit, или использовать HttpModule, который это делает.

Любой совет?

Ответов (6)

Решение

Я делал это раньше, я делал именно то, что вы описали (все страницы были унаследованы от настраиваемой страницы с событием OnPreInit). Также у меня был собственный Application_PreRequestHandlerExecute в моем Global.asax.cs для настройки Page.StyleSheetTheme для внесения изменений изображения / css, которые не требовали другой главной страницы.

Как насчет того, чтобы вместо двух разных главных страниц иметь одну главную страницу, которая динамически загружает различные пользовательские элементы управления и HTML-литералы содержимого?

Наследуйте все свои страницы от базового класса, например

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";
    }
}

Достаточно легко обработать PreInit и вставить одну строку кода, необходимую для загрузки правильной мастер-страницы.

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

В отсутствие какой-либо веской причины не идти по этому пути, я бы поступил так, независимо от того, где вы обрабатываете PreInit.

Мне любопытно, что решает, как должна выглядеть страница? Это пользователь нажимает кнопку, чтобы изменить тему? Основан ли он на URL-адресе, который использовался для перехода на сайт?

Код программной части поддерживается на мастер-страницах, поэтому вы можете добавить логику в свою единую мастер-страницу, чтобы решить, что следует отображать.

Я видел, как несколько сайтов устанавливали файлы cookie на основе щелчков пользователя (для изменения размера шрифта или ширины страницы), а затем применяли разные файлы CSS в зависимости от значения этих файлов cookie. Если файл cookie отсутствует, отобразите внешний вид по умолчанию.

РЕДАКТИРОВАТЬ:

Еще одна мысль, если вы просто пытаетесь отключить CSS, - это настроить тег стиля для работы на сервере и назначить ему свойства во время выполнения. И снова это потребует использования одной главной страницы и помещения кода программной части главной страницы, возможно, в обработчике событий PreInit.

Поскольку я никогда не реализовывал это решение, я не уверен, должен ли весь тег <HEAD> работать на сервере или нет.


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

Я чувствую твою боль. Я безуспешно искал проблему в течение часа (если не больше). Когда у вас сотни страниц, это не просто краткий ответ, когда можно сказать «просто вызовите его из PreInit на каждой странице». Но потом я понял, что трачу больше времени на поиск решения, чем на то, чтобы просто делать это на каждой странице.

Однако я хотел установить MasterPageFile на основе свойства Profile, чтобы на каждую страницу приходилось около 5 строк кода - кошмар ремонтопригодности. И вообще, «не повторяйся», да?

Поэтому я создал метод расширения в модуле в папке App_Code, чтобы сделать его проще и удобнее в обслуживании.

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