ASP.NET MVC3 _ViewStart設定Layout後用RenderAction的注意事項
3/24 TW MVC第一次活動圓滿的結束了,雖然是RC,但也來了不少願意聽我們分享的好朋友。
社群最大的好處就是分享以及回饋,當天有朋友提了一些問題,我們會蒐集起來利用每週四聚會
或是平日的時間一一回覆的。
回到主題,在MVC3中,Views資料夾下的_ViewStart.cshtml是可以設定預設的Layout的,
在MVC3預設專案中,_ViewStart.cshtml會長這樣
也就是說,凡是有在頁面上沒有特別指定Layout的話,就會預設使用此設定。
一般來說是滿方便的,但有時太方便也是會出一點小狀況
在頁面上,會呼叫 Html.Action 或 Html.RenderAction (兩者只是回傳方式不同而已)
指定Controller及Action並返回指定的頁面,而在Controller內要return View時,
若是用ViewResult返回,而頁面上又沒特別指定Layout的話,就會造成Layout被重複載入;
若是此Html.Action是在Layout上呼叫,更會造成無限迴圈的慘劇…
如上圖,呼叫的地方重覆的載入了Layout。
此種情況最常發生在呼叫 Html.Action 或是利用Ajax呼叫某個Controller與Action後返回頁面時,容易疏忽
了頁面會預設使用_ViewStart中預設的Layout。
解決辦法大概有下列幾種:
- 在 Action return 時,使用return PartialView(); PartialViewResult是不會載入Layout的。
- 在ChildAction 回傳的View中,明確的指定這個頁面的Layout為null或是空字串。
- 不要在_ViewStart中指定Layout,但這應該是下下策了。可視情況使用此方法。
另外補一點小知識,例如_ViewStart或是_Layout都會使用"_"當作前綴字,這是因為不希望以此方式命名
文件被直接的訪問,因此只要是"_"開頭的,被直接瀏覽時就會出現以下錯誤
另外還有一點就是,_ViewStart.cshtml的找尋規則跟Web.config有點類似,會先從離目標文件同層的
資料夾開始找,如果沒有的話再繼續到父資料夾找。因此實際上是可以配置很多個_ViewStart在不同
的資料夾內的。