2009-06-03 53 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美分的另一个[不一定推荐]方式。