2009-06-03 52 views
81

有沒有人知道如何在呈現視圖之前確定控制器內是否存在特定視圖名稱?在Asp.Net MVC中是否存在視圖?

我有一個要求,動態確定要呈現的視圖的名稱。如果一個視圖以該名稱存在,那麼我需要渲染該視圖。如果自定義名稱沒有視圖,那麼我需要呈現默認視圖。

我想我的控制器內做類似下面的代碼的東西:

public ActionResult Index() 
{ 
    var name = SomeMethodToGetViewName(); 

    //the 'ViewExists' method is what I've been unable to find. 
    if(ViewExists(name)) 
    { 
     retun View(name); 
    } 
    else 
    { 
     return View(); 
    } 
} 

感謝。

+10

只是閱讀這個標題,它看起來像一個非常深刻的哲學問題。 – 2014-04-24 08:04:03

回答

136
private bool ViewExists(string name) 
{ 
    ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, name, null); 
    return (result.View != null); 
} 

對於那些想要複製/粘貼擴展方法:

public static class ControllerExtensions 
{ 
    public static bool ViewExists(this Controller controller, string name) 
    { 
     ViewEngineResult result = ViewEngines.Engines.FindView(controller.ControllerContext, name, null); 
     return (result.View != null); 
    } 
} 
+2

這可能會更好。我不知道ViewEngines集合本身有一個FindView方法。 – 2009-06-03 20:39:33

+0

看起來像是要工作。謝謝戴夫。 – 2009-06-04 16:11:38

+1

但如何檢查視圖是否存在其他控制器? – SOReader 2013-03-20 15:22:48

15

什麼嘗試類似如下假設你使用的只有一個視圖引擎:

bool viewExists = ViewEngines.Engines[0].FindView(ControllerContext, "ViewName", "MasterName", false) != null; 
+0

看起來像這個被髮布前3分鐘接受的答案,但沒有愛?從我+1。 – 2012-12-19 05:17:36

+0

@TrevordeKoekkoek ...嗯... + 1 – 2013-12-06 08:45:12

2

如果您想要在多個控制器操作中重複使用此操作,並基於Dave給出的解決方案,您可以按如下方式定義自定義視圖結果:

public class CustomViewResult : ViewResult 
{ 
    protected override ViewEngineResult FindView(ControllerContext context) 
    { 
     string name = SomeMethodToGetViewName(); 

     ViewEngineResult result = ViewEngines.Engines.FindView(context, name, null); 

     if (result.View != null) 
     { 
      return result; 
     } 

     return base.FindView(context); 
    } 

    ... 
} 

然後在你的行動只要你把你的自定義視圖的一個實例:

public ActionResult Index() 
{ 
    return new CustomViewResult(); 
} 
5

這裏做

try 
{ 
    @Html.Partial("Category/SearchPanel/" + Model.CategoryKey) 
} 
catch (InvalidOperationException) { } 
+0

這是測試是否存在.cshtml文件。這個問題並不是真正的答案,但另一個問題,這裏的鏈接是不正確的關閉,所以我在這裏留下我的答案 – 2013-05-08 23:58:11

+1

這實際上是我的用途,因爲我正在尋找一種方式來使用文化特定局部視圖。所以我只是用文化特定的視圖名稱調用它,然後在catch中調用默認視圖。我在一個實用函數中這樣做,所以我無法像'FindView'方法那樣訪問'ControllerContext'。 – awe 2013-11-28 11:14:07

+4

基於異常的流量控制是一種代碼異味... – ErikE 2014-03-13 20:34:33

1
ViewEngines.Engines.FindView(ViewContext.Controller.ControllerContext, "View Name").View != null 

我的2美分的另一個[不一定推薦]方式。