2009-08-12 22 views
35

Ho una vista parziale (controllo) utilizzata in più pagine di visualizzazione e devo passare il nome della vista corrente al controller, quindi se c'è, ad es. errori di convalida, posso ri-disegnare la vista originale.Recupera il nome della vista corrente in ASP.NET MVC?

Un modo soluzione per farlo sarebbe (nei metodi controllore)

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

e quindi nella stessa parziale, renderlo come

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

domanda è - c'è qualche proprietà o sintassi che posso usare per recuperarlo direttamente invece di impostarlo dal controller? Ho provato l'ovvio:

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

ma questo non funziona. Cosa mi manca qui?

Grazie.

+1

Questo è un po 'di stumper. Ho pensato che dovrebbe essere possibile dal momento che è possibile ottenere il nome della vista dal risultato dell'azione durante il test del controller ... ma non sono chiaro su come recuperarlo dall'interno della Vista stessa. In attesa di risposta ... – womp

risposta

34

Beh, se non ti dispiace avere il codice legato allo specifico motore di visualizzazione che si sta utilizzando, si può guardare la proprietà ViewContext.View per gettarlo ai WebFormView

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

Credo che ti porterà il nome della vista alla fine.

MODIFICA: Haacked è assolutamente azzeccato; per rendere le cose un po 'più ordinato ho avvolto la logica in un metodo di estensione in questo 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")); 
     } 
    } 
} 

che sembra fare esattamente quello che cercavo.

+1

solo una domanda di follow-up poiché ha quasi 2 anni: non c'è un modo più semplice di ottenere un nome di visualizzazione Razor con ASP.NET MVC 3? –

+0

puoi aiutare questa povera anima: P? http: // StackOverflow.it/questions/6246082/mvc3-how-to-get-currently-executing-view-or-partial-view-programatically-inside/6246173 # 6246173 –

+3

È possibile eseguire il cast su 'BuildManagerCompiledView' invece di WebFormView. RazorView si estende anche da esso. –

8

se si desidera solo il nome dell'azione allora questo sarebbe fare il trucco:

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

then Html.ViewName() :) –

+7

Ho bisogno del nome della vista, non del nome dell'azione. La vista non è contenuta nei dati del percorso da nessuna parte; è determinato dal valore restituito dal metodo del controller. –

+1

-1 Vedere il mio commento alla risposta di Anthony Johnston. Questo è totalmente fuorviante per i novizi !! – JotaBe

0

Non dovresti essere utilizzando un metodo di validazione come attrezzi Nerd cena?

In questo modo in realtà non è necessario eseguire tutto ciò e si può semplicemente restituire la vista.

-2

appena scritto un thingy blog su questo utilizzo

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: Sì, questo non sta per dare il nome della vista come il primo commento Stati, ti dà il controller e l'azione. Ma lasciandolo qui è prezioso sapere che non è così.

+0

Questa è un'idea interessante e mi piace. L'unico problema è che è possibile per un controller restituire in modo condizionale una vista a seconda di alcuni stati, quindi questo non è necessariamente associato a una vista specifica. – NightOwl888

+4

-1. Come afferma il commento precedente, è molto frequente restituire una visualizzazione diversa da un'azione in base al risultato dell'azione. O perché diverse azioni condividono una singola vista. Quindi questo è molto inaffidabile. – JotaBe

11

ho avuto lo stesso problema ed è così che ho risolto:

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

Poi nella vista:

var name = Html.CurrentViewName(); 

o semplicemente

@Html.CurrentViewName() 
+0

eccetto che questo non funziona se includi altre pagine tramite Html.Partial() perché quello che ottieni è la pagina inclusa, non lo – ekkis

3

Se si desidera ottenere il nome file all'interno di una vista parziale, questo sembra funzionare:

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

E in vista parziale, si dovrebbe fare qualcosa di simile:

var filename = Html.GetViewFileName(this); 

o questo:

@Html.GetViewFileName(this) 

Si prega di fare commento, se questo non è un buon approccio - eventuali alternative?

+0

incluso, questo funziona bene per le pagine incluse. Vorrei solo raccomandare che si possa ottenere il nome della vista corrente come questo 'html.ViewDataContainer.GetType(). FullName' che ti evita di dover passare la vista nel metodo – ekkis

0

Ho avuto lo stesso problema di recente e il frammento di codice che ho trovato risolto il mio problema.

L'unico inconveniente è che Request.UrlReferrer potrebbe essere nullo in alcuni casi. Un po 'in ritardo ma sembrava funzionare per me e ho coperto tutte le basi di Request.UrlReferrer non essendo nullo.

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

La soluzione più semplice è utilizzare ViewBag.

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

Nella pagina cshtml

@{ 
var viewName = ViewBag.CurrentView; 
} 

Oppure,

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

Ma questo non è un metodo valido quando si usa una vista rende anche partial. Stavo osservando questa domanda a causa di un plug-in di suggerimento personalizzato che è abbastanza intelligente solo usando l'attributo personalizzato sull'elemento, per ottenere la vista corrente, il nome della proprietà e recupera i metadati da visualizzare in un'icona "info" di elemento per una descrizione e regole aziendali dipendenti da un altro campo per l'utente finale. Così due viste separate possono avere un nome di campo simile per due diversi modelli di vista all'interno di una vista a causa di parziali di rendering. Lavorerà su VISTA GENERALE RESTITUITO ALLA VOLTA SE. – Casey

1

Se siete alla ricerca di soluzione per nucleo asp.net è possibile utilizzare:

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

Questo restituirà il nome della vista corrente.

Problemi correlati