2013-07-29 67 views
4

在asp.net MVC 3有沒有一種方法來覆蓋從控制器或操作過濾器的視圖中設置的佈局聲明?如何覆蓋視圖佈局聲明

@{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
}

我試圖覆蓋在OnResultExecuted的MasterName財產或類似下面的代碼片段的OnResultExecuting,但無濟於事。

public override void OnResultExecuting(ResultExecutingContext filterContext) 
{ 
    var view = filterContext.Result as ViewResult; 
    view.MasterName = null; 
}

回答

3

您可以創建一個動作過濾器來覆蓋佈局文件,但如果你想刪除它,你必須創建一個空的佈局文件,而不是分配主屬性設置爲null的。就像這樣:

public class OverrideLayoutFilter : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     var view = filterContext.Result as ViewResult; 
     view.MasterName = "_LayoutEmpty"; 
     base.OnResultExecuting(filterContext); 
    } 
} 

控制器:

public class HomeController : Controller 
{ 
    [OverrideLayoutFilter] 
    public ActionResult Index() 
    { 
     return View(); 
    } 
} 

現在這個新佈局文件需要被放置在SharedFolder,你只把RenderBody函數內部

_LayoutEmpty.cshtml

@RenderBody() 

注意:如果您在視圖中定義了要覆蓋佈局的部分,我們也必須定義那些空白內容的部分。

+0

你知道爲什麼設置MastName爲空不起作用嗎? – Victor

+0

我不確定,但我認爲它與MVC不知道空值已被「由用戶」設置的事實有關,因此它假定它需要加載默認佈局文件。這只是一個猜測。 –

2

使用ViewBag 當你需要改變佈局打電話的動作,並把新的佈局(甚至零)的viewbag。

@{ 
    Layout = ViewBag.layout; 
} 

和行動

if(something) 
    ViewBag.layout = "~/Views/Shared/whatever.cshtml"; 
else 
    ViewBag.layout = null; 
+0

我m尋找一種方法來保持我的佈局聲明在視圖中,並且只是有一個業務規則來決定何時從控制器切換它。 – Victor

2

另一個地方,你可以控制佈局是在_ViewStart.cshtml內。

在這裏,您可以執行所需的邏輯並以編程方式指定要使用的佈局。這使您可以將邏輯放在一個地方,並將其保留在視圖外。

@{ 
    if(myBusinessRule) 
    { 
     Layout = "~/Views/Shared/_Layout.cshtml"; 
    } 
    else 
    { 
     Layout = "~/Views/Shared/_SecondaryLayout.cshtml"; 
    } 
} 

Blog post where it was introduced by Scott Gu