.NET MVC 3 Программно установленный макет - PullRequest
5 голосов
/ 17 октября 2011

В веб-приложении .NET Razor я пытаюсь программно установить Layout. Я не могу использовать _ViewStart.cshtml и не хочу устанавливать @{ Layout = "..." } на каждой странице. Вот что я придумал:

База WebViewPage класс:

public abstract class SitePage<T> : System.Web.Mvc.WebViewPage<T>
{
    private object _layout;

    public new dynamic Layout { get { return _layout; } }

    public override void InitHelpers()
    {
        base.InitHelpers();
        _layout = "~/Themes/" + Settings.Theme + "/Views/_Layout.cshtml";
    }
}

А в приложении web.config я указываю все представления, чтобы использовать эту базовую страницу. Но, похоже, Layout никогда не используется. Что здесь может быть не так?

Ответы [ 2 ]

9 голосов
/ 17 октября 2011

Класс WebViewPage наследуется от WebPageBase, у которого есть свойство с именем Layout, например:

public override string Layout { get; set; }

. Вы можете переопределить свойство Layout или изменить логику _layout для достижения своей цели.,Например:

public abstract class SitePage<T> : System.Web.Mvc.WebViewPage<T> {

    // set this modifier as protected, to make it accessible from view-pages
    protected string _layout{
        get {
            return base.Layout;
        }
        set {
            base.Layout = value;
        }
    }

    public override void InitHelpers() {
        base.InitHelpers();
        _layout = "~/Themes/" + Settings.Theme + "/Views/_Layout.cshtml";
    }
}

и / или на странице просмотра вы также можете установить его:

@{
    _layout = "_Your_Special_Layout.cshtml";
}

ОБНОВЛЕНИЕ : использование флага, чтобы избежать стека-процесс потока в назначении _layout более одного раза:

public abstract class SitePage<T> : System.Web.Mvc.WebViewPage<T> {

    public bool LayoutAssigned {
        get {
            return (ViewBag.LayoutAssigned == true);
        }
        set {
            ViewBag.LayoutAssigned = value;
        }
    }

    // set this modifier as protected, to make it accessible from view-pages
    protected string _layout{
        get {
            return base.Layout;
        }
        set {
            base.Layout = value;
        }
    }

    public override void InitHelpers() {
        base.InitHelpers();
        if(!LayoutAssigned) {
            _layout = "~/Themes/" + Settings.Theme + "/Views/_Layout.cshtml";
            LayoutAssigned = true;
        }
    }
}
5 голосов
/ 11 июля 2013

Я пытался добиться того же самого сейчас, внедряя пользовательский WebViewPage, однако изменение WebViewPage.Layout в моем пользовательском классе не имело никакого эффекта (как вы также обнаружили).

В конце концов я изменил свой _ViewStart.cshtml, чтобы иметь этот код:

@{
    this.Layout = this.Request.QueryString["print"] == "1" 
        ? "~/Views/Layout/_Print.cshtml"
        : "~/Views/Layout/_Layout.cshtml";
}

Возможно, он не реализован так, как вы хотели, но он, безусловно, сохраняет вещи сухими, и это главное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...