2009-08-12 6 views
35

J'ai une vue partielle (contrôle) qui est utilisée sur plusieurs pages d'affichage, et j'ai besoin de renvoyer le nom de la vue actuelle au contrôleur - donc s'il y a par exemple. erreurs de validation, je peux redessiner la vue originale.Récupérez le nom de vue actuel dans ASP.NET MVC?

Une façon solution de le faire serait (dans les méthodes de régulation)

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

puis dans la même partielle, rendre comme

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

La question est - est-il un bien ou syntaxe que je peux utiliser pour récupérer cela directement au lieu de le définir à partir du contrôleur? J'ai essayé l'évidence:

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

mais cela ne fonctionne pas. Qu'est-ce que j'oublie ici?

Merci.

+1

Ceci est un peu un choc. Je pensais que ce devrait être possible puisque vous pouvez obtenir le nom de la vue à partir du résultat de l'action pendant le test du contrôleur ... mais je ne suis pas clair sur la façon de le récupérer à l'intérieur de la vue elle-même. Dans l'attente d'une réponse ... – womp

Répondre

34

Eh bien, si ça ne vous dérange pas d'avoir votre code lié au moteur de vue spécifique que vous utilisez, vous pouvez regarder la ViewContext.View propriété et de le jeter à WebFormView

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

Je crois que vous obtiendrez le nom de la vue à la fin.

EDIT: Haacked est absolument spot-on; pour rendre les choses un peu plus propre que j'ai Enveloppez la place logique dans une méthode d'extension comme ceci:

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

qui semble faire exactement ce que je cherchais.

+1

juste une question de suivi puisque c'est près de 2 ans: il n'y a pas de moyen plus simple d'obtenir un nom de vue Razor avec ASP.NET MVC 3? –

+0

pouvez-vous aider cette pauvre âme: P? http: // stackoverflow.com/questions/6246082/mvc3-comment-obtenir-en-cours-d'exécution-en-vue-ou-partielle-en-vue-programmatique-intérieur/6246173 # 6246173 –

+3

Vous pouvez convertir en 'BuildManagerCompiledView' au lieu de WebFormView. RazorView s'étend aussi de lui. –

8

Si vous voulez juste le nom d'action alors ce serait faire l'affaire:

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

puis Html.ViewName() :) –

+7

J'ai besoin du nom de la vue, pas du nom de l'action. La vue n'est pas contenue dans les données de route n'importe où; Il est déterminé par la valeur de retour de la méthode du contrôleur. –

+1

-1 Voir mon commentaire sur Anthony Johnston. Ceci est totalement trompeur pour les novices !! – JotaBe

0

ne devrait pas vous d'utiliser une méthode de validation comme outils Dîner Nerd?

De cette façon, vous n'avez pas vraiment besoin de faire tout cela et vous pouvez simplement retourner la vue.

-2

viens d'écrire un blog thingy sur ce

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

utilisation

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

EDIT: Oui cela ne va pas vous donner le nom de vue que les premiers états de commentaire, cela vous donne le contrôleur et l'action. Mais en laissant cela ici, il est important de savoir que ce n'est pas le cas.

+0

Ceci est une idée intéressante et je l'aime. Le seul problème est qu'il est possible pour un contrôleur de renvoyer conditionnellement une vue en fonction d'un état, donc cela ne correspond pas nécessairement à une vue spécifique. – NightOwl888

+4

-1. Comme l'indique le commentaire précédent, il est très fréquent de renvoyer une vue différente d'une action en fonction du résultat de l'action. Ou parce que plusieurs actions partagent une même vue. Donc, c'est très peu fiable. – JotaBe

11

J'ai eu le même problème et voilà comment je l'ai résolu:

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

Puis dans la vue:

var name = Html.CurrentViewName(); 

ou simplement

@Html.CurrentViewName() 
+0

sauf que cela ne fonctionne pas si vous incluez d'autres pages via Html.Partial() parce que ce que vous obtenez est la page y compris, pas le – ekkis

3

Si vous voulez obtenir la nom de fichier à partir d'une vue partielle, cela semble fonctionner:

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

Et dans la vue partielle, vous devez faire quelque chose comme ceci:

var filename = Html.GetViewFileName(this); 

ou ceci:

@Html.GetViewFileName(this) 

S'il vous plaît ne faisons aucun commentaire si ce n'est pas une bonne approche - des solutions de rechange?

+0

inclus cela fonctionne bien pour les pages incluses. Je recommanderais seulement que l'on puisse obtenir le nom de la vue actuelle comme ceci 'html.ViewDataContainer.GetType(). FullName' qui vous évite d'avoir à passer la vue dans la méthode – ekkis

0

J'ai eu le même problème récemment et l'extrait de code que j'ai proposé a résolu mon problème. Le seul problème est que Request.UrlReferrer peut être nul dans certains cas. Bit tard, mais semblait travailler pour moi et j'ai couvert toutes les bases de Request.UrlReferrer n'étant pas nul.

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

La solution la plus simple utilise ViewBag.

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

Sur la page cshtml

@{ 
var viewName = ViewBag.CurrentView; 
} 

Ou,

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

Mais ce n'est pas une méthode viable en utilisant une vue qui rend également partiels. Je regardais cette question en raison d'un plugin d'imbriquer tip tip personnalisé qui est assez intelligent seulement en utilisant l'attribut personnalisé sur l'élément, pour obtenir la vue actuelle, le nom de la propriété, et récupère les méta-données à afficher dans une icône "info" élément pour une description, et les règles métier dépendant d'un autre champ pour l'utilisateur final. Ainsi, deux vues séparées peuvent avoir un nom de champ similaire pour deux modèles de vue différents dans une vue en raison des partiels de rendu. TRAVAILLERA SUR UNE VUE GÉNÉRALE RETOURNÉE À UNE HEURE. – Casey

1

Si vous êtes à la recherche de solution pour le cœur de asp.net vous pouvez utiliser:

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

Cette retournera le nom de la vue actuelle.

Questions connexes