2009-06-03 23 views
81

¿Alguien sabe cómo es posible determinar si existe un nombre de vista específico dentro de un controlador antes de mostrar la vista?¿Existe una vista en Asp.Net MVC?

Tengo un requisito para determinar dinámicamente el nombre de la vista para representar. Si existe una vista con ese nombre, entonces necesito renderizar esa vista. Si no hay vista por el nombre personalizado, entonces necesito renderizar una vista predeterminada.

me gustaría hacer algo similar al siguiente código dentro de mi controlador:

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(); 
    } 
} 

Gracias.

+10

Acabo de leer el título de esto, parece una pregunta filosófica muy profunda. –

Respuesta

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

Para aquellos que buscan un método de extensión de copiar/pegar:

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

Esto es probablemente mejor. No sabía que había un método FindView fuera de la colección ViewEngines. –

+0

Parece que va a funcionar. Gracias Dave. –

+1

¿Pero cómo verificar si la vista existe para otro controlador? – SOReader

15

¿Qué hay de tratar algo como lo siguiente suponiendo que está utilizando el motor único punto de vista:

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

parece que este fue publicado 3 minutos antes de la respuesta aceptada y sin embargo no hay amor ?! +1 de mi parte –

+0

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

2

Si desea volver a utilizar esto en varias acciones de controlador, basándose en la solución dada por Dave, puede definir un resultado de vista personalizado de la siguiente manera:

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); 
    } 

    ... 
} 

Luego, en su acción simplemente devuelva una instancia de la vista personalizada:

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

Ésta es otra manera [no necesariamente recomendado] de hacerlo

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

esto es para probar la existencia de una vista parcial dentro de un archivo .cshtml. no es realmente una respuesta para esta pregunta, pero otra pregunta que los enlaces aquí se cerró incorrectamente, así que dejo mi respuesta aquí –

+1

Esto fue realmente perfecto para mi uso, ya que estaba buscando una manera de utilizar una cultura específica vista parcial. Así que acabo de llamar a esto con el nombre de la vista específica de la cultura, y luego llamé a la vista predeterminada dentro de la captura.Y estaba haciendo esto en una función de utilidad, así que no tenía acceso al 'ControllerContext' como lo requiere el método' FindView'. – awe

+4

El control de flujo basado en excepciones es un olor a código ... – ErikE

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

Mis 2 centavos.

Cuestiones relacionadas