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

问题描述 投票:0回答:11

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

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

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

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

谢谢。

.net asp.net-mvc
11个回答
37
投票

如果您不介意将代码绑定到您正在使用的特定视图引擎,您可以查看

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

这似乎正是我所追求的。


17
投票

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

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

9
投票

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

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

5
投票

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

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

在cshtml页面上

@{
var viewName = ViewBag.CurrentView;
}

或者,

((RazorView)ViewContext.View).ViewPath

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
投票

如果您正在寻找 ASP.NET Core 的解决方案,您可以使用:

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

这将返回当前视图名称。


0
投票

你不应该使用像 Nerddinner 实现的验证方法吗?

这样您实际上不需要执行所有这些操作,只需返回视图即可。


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

0
投票

您可以使用剃须刀:

在您的视图标题中

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

在您的视图 HTML 中

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

在你的html中使用变量@_nameCurrentView

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

或在你的行动中使用

  ViewData["Title"]

0
投票

你可以这样尝试

    public static string GetViewFromUrl(this string url)
    {
        // Regex to extract the controller and action (last two segments)
        var match = Regex.Match(url, @"https?:\/\/[^\/]+\/([^\/]+)(?:\/([^\/\?]+))?");

        // If a match is found, extract the controller and action
        if (match.Success)
        {
            // Extract action if exists, otherwise default to "Index"
            string action = match.Groups[2].Success ? match.Groups[2].Value : "Index";
            return action;
        }

        // If the URL doesn't match the expected pattern, return "Index"
        return "Index";
    }

这将始终返回 ActionName

我是这样用的

        string actionName = context.HttpContext.Request.Headers["Referer"].ToString().GetViewFromUrl();

-3
投票

刚刚写了一篇关于此的博客

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

编辑:是的,这不会为您提供第一个注释所述的视图名称,它为您提供控制器和操作。但把它留在这里是很有价值的,因为知道它没有。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.