Получить текущее имя представления в 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)%>" />
но это не работает. Что мне здесь не хватает?
Спасибо.
Ответы
Ответ 1
Хорошо, если вы не возражаете, чтобы ваш код привязан к определенному движку просмотра, который вы используете, вы можете посмотреть свойство 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"));
}
}
}
который, похоже, делает то, что я был после.
Ответ 2
У меня была та же проблема и что я решил это:
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()
Ответ 3
Если вам просто нужно имя действия, это сделает трюк:
public static string ViewName(this HtmlHelper html)
{
return html.ViewContext.RouteData.GetRequiredString("action");
}
Ответ 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)
Прокомментируйте это, если это не хороший подход - любые альтернативы?
Ответ 5
Самое простое решение - использовать ViewBag.
public ActionResult Index()
{
ViewBag.CurrentView = "Index";
return View();
}
На странице cshtml
@{
var viewName = ViewBag.CurrentView;
}
Или
((RazorView)ViewContext.View).ViewPath
Ответ 6
Если вы ищете решение для ядра asp.net, вы можете использовать:
@System.IO.Path.GetFileNameWithoutExtension(ViewContext.View.Path)
Это вернет текущее имя вида.
Ответ 7
Не следует ли использовать метод проверки, например, как Nerd Dinner?
Таким образом, вам не нужно все это делать, и вы можете просто вернуть представление.
Ответ 8
У меня была такая же проблема в последнее время, и фрагмент кода, который я придумал, решил мою проблему.
Единственное падение состоит в том, что Request.UrlReferrer может быть пустым в некоторых случаях. Немного поздно, но, похоже, работал у меня, и я рассмотрел все основания Request.UrlReferrer, которые не являются нулевыми.
if (Request.UrlReferrer != null)
{
var viewUrl = Request.UrlReferrer.ToString();
var actionResultName = viewUrl.Substring(viewUrl.LastIndexOf('/'));
var viewNameWithoutExtension = actionResultName.TrimStart('/');
}
Ответ 9
Только что написал блог об этом
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}") %>">
РЕДАКТИРОВАТЬ: Да, это не даст вам имя представления в качестве первого состояния комментариев, оно даст вам контроллер и действие. Но оставляя это здесь как ценное, чтобы знать, что это не так.