在ASP.NET MVC中检索当前视图名称?

时间:2009-08-12 21:15:38

标签: .net asp.net-mvc

我有一个在多个视图页面中使用的局部视图(控件),我需要将当前视图的名称传递回控制器 - 所以如果有的话,例如验证错误,我可以重新绘制原始视图。

解决方法是(在控制器方法中)

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

然后在部分本身中,将其渲染为

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

问题是 - 是否有一些属性或语法我可以直接检索它而不是从控制器设置它?我已经尝试过显而易见的事了:

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

但这不起作用。我在这里缺少什么?

感谢。

10 个答案:

答案 0 :(得分:36)

如果您不介意将代码绑定到您正在使用的特定视图引擎,那么您可以查看ViewContext.View属性并将其强制转换为WebFormView

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

我相信最终会得到你的观点名称。

编辑: Haacked绝对是现货;为了让事情变得更整洁,我把逻辑包装在一个像这样的扩展方法中:

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

这似乎完全符合我的目的。

答案 1 :(得分:14)

我遇到了同样的问题,这就是我解决问题的方法:

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

然后在视图中:

var name = Html.CurrentViewName();

或只是

@Html.CurrentViewName()

答案 2 :(得分:9)

如果您只想要动作名称,那么这就可以解决问题:

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

答案 3 :(得分:4)

如果你想从局部视图中获取文件名,这似乎有效:

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

在局部视图中,您应该执行以下操作:

var filename = Html.GetViewFileName(this);

或者这个:

@Html.GetViewFileName(this)

如果这不是一个好方法,请发表评论 - 任何替代方案?

答案 4 :(得分:3)

最简单的解决方案是使用ViewBag。

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

在cshtml页面上

@{
var viewName = ViewBag.CurrentView;
}

或者,

((RazorView)ViewContext.View).ViewPath

答案 5 :(得分:1)

如果您正在寻找asp.net核心的解决方案,您可以使用:

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

这将返回当前视图名称。

答案 6 :(得分:0)

您是否应该使用像Nerd Dinner工具这样的验证方法?

这样你实际上不需要做所有这些,你只需返回视图。

答案 7 :(得分:0)

我最近遇到了同样的问题,我提出的代码片段解决了我的问题。

唯一的缺点是Request.UrlReferrer在某些情况下可能为null。有点迟,但似乎对我有用,我覆盖了Request.UrlReferrer的所有基础都不为空。

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

答案 8 :(得分:0)

您可以使用Razor:

在您的视图标题中

@{
    ViewData["Title"] = "YourViewName";    
}

在您的View HTML中

@{
   var _nameCurrentView = ViewContext.ViewData["Title"];
}

在您的html中使用变量@_nameCurrentView

  <li class="breadcrumb-item active">@_nameCurrentView</li>

或在行动中使用

  ViewData["Title"]

答案 9 :(得分:-2)

刚刚写了一篇博客,关于这个

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

编辑:是的,这不会给你视图名称作为第一个评论说明,它给你控制器和动作。但是把它留在这里是有价值的,知道它没有。