2009-08-12 14 views
35

Tengo una vista parcial (control) que se utiliza en varias páginas de visualización, y necesito devolver el nombre de la vista actual al controlador, por lo que si hay, p. errores de validación, puedo volver a dibujar la vista original.¿Recuperar el nombre de vista actual en ASP.NET MVC?

Una manera solución de hacerlo sería (en los métodos de controlador)

var viewName = "Details"; // or whatever 
ViewData["viewName"] = viewName; 
return(View(viewName, customer)); 

y luego en el propio parcial, la haré tan

<input type="hidden" name="viewName" 
    value="<%=Html.Encode(ViewData["viewName"])%>" /> 

La pregunta es - ¿hay alguna propiedad o sintaxis que puedo usar para recuperar esto directamente en lugar de configurarlo desde el controlador? He intentado lo obvio:

<input type="hidden" name="viewName" 
    value="<%=Html.Encode(this.Name)%>" /> 

pero esto no funciona. ¿Que me estoy perdiendo aqui?

Gracias.

+1

Esto es un poco stumper. Pensé que debería ser posible ya que puedes obtener el nombre de la vista del resultado de la acción durante la prueba del controlador ... pero no tengo claro cómo recuperarlo desde la propia Vista. Esperando una respuesta ... – womp

Respuesta

34

Bueno, si no te importa tener su código atado al motor vista específica que está utilizando, se puede ver en la propiedad ViewContext.View y echarlo a WebFormView

var viewPath = ((WebFormView)ViewContext.View).ViewPath; 

creo que les permite conocer el nombre de la vista al final.

EDIT: Haacked es absolutamente en el clavo; para hacer las cosas un poco más limpio que he envuelto la lógica en un método de extensión de este modo:

public static class IViewExtensions { 
    public static string GetWebFormViewName(this IView view) { 
     if (view is WebFormView) { 
      string viewUrl = ((WebFormView)view).ViewPath; 
      string viewFileName = viewUrl.Substring(viewUrl.LastIndexOf('/')); 
      string viewFileNameWithoutExtension = Path.GetFileNameWithoutExtension(viewFileName); 
      return (viewFileNameWithoutExtension); 
     } else { 
      throw (new InvalidOperationException("This view is not a WebFormView")); 
     } 
    } 
} 

que parece hacer exactamente lo que yo buscaba.

+1

solo una pregunta de seguimiento ya que tiene casi 2 años: ¿no hay alguna forma más sencilla de obtener un nombre de vista Razor con ASP.NET MVC 3? –

+0

¿Puedes ayudar a esta pobre alma: P? http: // stackoverflow.com/questions/6246082/mvc3-how-to-get-currently-executing-view-or-partial-view-programáticamente-inside/6246173 # 6246173 –

+3

Puede convertir a 'BuildManagerCompiledView' en lugar de WebFormView. RazorView también se extiende desde allí. –

8

Si lo que desea es el nombre de la acción, entonces esto sería hacer el truco:

public static string ViewName(this HtmlHelper html) 
{ 
    return html.ViewContext.RouteData.GetRequiredString("action"); 
} 
+0

then Html.ViewName() :) –

+7

Necesito el nombre de la vista, no el nombre de la acción. La vista no está contenida en los datos de ruta en ningún lado; está determinado por el valor de retorno del método del controlador. –

+1

-1 Ver mi comentario a la respuesta de Anthony Johnston. ¡Esto es totalmente engañoso para los principiantes! – JotaBe

0

No deberías estar usando un método de validación como implementos del empollón de la cena?

De esta forma, no es necesario que haga todo esto y solo puede devolver la Vista.

-2

acabo de escribir una cosita blog sobre este uso

http://www.antix.co.uk/A-Developers-Blog/Targeting-Pages-with-CSS-in-ASP.NET-MVC

/// <summary> 
    /// <para>Get a string from the route data</para> 
    /// </summary> 
    public static string RouteString(
     this ViewContext context, string template) { 

    foreach (var value in context.RouteData.Values) { 

    template = template.Replace(string.Format("{{{0}}}", 
      value.Key.ToLower()), 
      value.Value == null 
       ? string.Empty 
       : value.Value.ToString().ToLower()); 
    } 

    return template; 
    } 

<body class="<%= ViewContext.RouteString("{controller}_{action}") %>"> 

EDIT: Si esto no se va a dar el nombre de vista como los primeros estados de comentarios, te da el controlador y la acción. Pero dejarlo aquí es valioso saber que no es así.

+0

Esta es una idea interesante y me gusta. El único problema es que es posible que un controlador devuelva condicionalmente una vista en función de algún estado, por lo que no necesariamente se asigna a una vista específica. – NightOwl888

+4

-1. Como dice el comentario anterior, es muy frecuente devolver una vista diferente de una acción dependiendo del resultado de la acción. O porque varias acciones comparten una sola vista. Entonces esto es muy poco confiable. – JotaBe

11

que tenían el mismo problema y así es como lo resolví:

namespace System.Web.Mvc 
{ 
    public static class HtmlHelperExtensions 
    { 
     public static string CurrentViewName(this HtmlHelper html) 
     { 
      return System.IO.Path.GetFileNameWithoutExtension(
       ((RazorView)html.ViewContext.View).ViewPath 
      ); 
     } 
    } 
} 

A continuación, en la vista:

var name = Html.CurrentViewName(); 

o simplemente

@Html.CurrentViewName() 
+0

excepto que esto no funciona si incluye otras páginas a través de Html.Partial() porque lo que obtiene es la página que incluye, no el – ekkis

3

Si desea obtener el nombre de archivo desde dentro de una vista parcial, esto parece funcionar:

public static class HtmlHelperExtensions 
{ 
    public static string GetViewFileName(this HtmlHelper html, object view) 
    { 
     return @"\\"+ view.GetType().FullName.Replace("ASP._Page_", "").Replace("_cshtml", ".cshtml").Replace("_", @"\\"); 
    } 
} 

Y en la vista parcial, usted debe hacer algo como esto:

var filename = Html.GetViewFileName(this); 

o esto:

@Html.GetViewFileName(this) 

favor hacer comentario si esto no es un buen enfoque - alguna alternativa?

+0

incluido, esto funciona bien para las páginas incluidas. Solo recomendaría que uno pueda obtener el nombre de la vista actual como este 'html.ViewDataContainer.GetType(). FullName' que le ahorra tener que pasar la vista al método – ekkis

0

Tuve el mismo problema recientemente y el fragmento de código que se me ocurrió resolvió mi problema.

El único inconveniente es que Request.UrlReferrer podría ser nulo en algunos casos. Un poco tarde pero parecía funcionar para mí y cubrí todas las bases de Request.UrlReferrer no siendo nulo.

if (Request.UrlReferrer != null) 
{ 
     var viewUrl = Request.UrlReferrer.ToString(); 
     var actionResultName = viewUrl.Substring(viewUrl.LastIndexOf('/')); 
     var viewNameWithoutExtension = actionResultName.TrimStart('/'); 
} 
2

La solución más fácil es usar ViewBag.

public ActionResult Index() 
    { 
     ViewBag.CurrentView = "Index"; 
     return View(); 
    } 

En la página cshtml

@{ 
var viewName = ViewBag.CurrentView; 
} 

O

((RazorView)ViewContext.View).ViewPath 
+0

, pero este no es un método viable cuando se utiliza una vista que también representa parciales. Estaba viendo esta pregunta debido a la escritura de un plugin de punta de herramienta personalizada que es lo suficientemente inteligente solo con el atributo personalizado en el elemento, para obtener la vista actual, el nombre de la propiedad y recuperar metadatos para que se muestren en un ícono de "información" elemento para una descripción, y las reglas de negocio dependen de otro campo para el usuario final. Por lo tanto, dos vistas separadas pueden tener un nombre de campo similar para dos modelos de vista diferentes en una vista debido a parciales de representación. FUNCIONARÁ EN LA VISIÓN GENERAL DEVUELTA A LA VEZ AUN CUANDO. – Casey

1

Si usted está buscando una solución para el núcleo asp.net puede utilizar:

@System.IO.Path.GetFileNameWithoutExtension(ViewContext.View.Path) 

Este devolverá el nombre de vista actual.

Cuestiones relacionadas