2009-06-03 3 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

Это, наверное, лучше. Я не знал, что был метод FindView вне самой коллекции ViewEngines. –

+0

Похоже, это сработает. Спасибо Дэйву. –

+1

Но как проверить, существует ли представление для другого контроллера? – SOReader

15

насчет попробовать что-то вроде следующих предполагая, что вы используете только один вид двигателя:

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

выглядит как этот был опубликован за 3 минуты до принятого ответа, и все же нет любви ?! +1 от меня. –

+0

@TrevordeKoekkoek ... hmmm ... + 1 –

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. это не является ответом на этот вопрос, но другой вопрос, который здесь ссылается, был некорректно закрыт, поэтому я оставляю свой ответ здесь –

+1

Это было на самом деле для моего использования, так как я искал способ использования определенной культуры частичный вид. Поэтому я только что назвал это с именем вида, специфичным для культуры, а затем вызвал представление по умолчанию внутри catch.И я делал это в функции утилиты, поэтому у меня не было доступа к 'ControllerContext', как нужно для метода FindView. – awe

+4

Управление потоком на основе исключений - это запах кода ... – ErikE

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

Мои 2 цента.

Смежные вопросы