我有一个在多个视图页面中使用的局部视图(控件),我需要将当前视图的名称传递回控制器 - 所以如果有的话,例如验证错误,我可以重新绘制原始视图。
解决方法是(在控制器方法中)
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)%>" />
但这不起作用。我在这里缺少什么?
感谢。
答案 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}") %>">
编辑:是的,这不会给你视图名称作为第一个评论说明,它给你控制器和动作。但是把它留在这里是有价值的,知道它没有。