Reputation: 54130
I have a partial view (control) that's used across several view pages, and I need to pass the name of the current view back to the controller - so if there's e.g. validation errors, I can re-draw the original view.
A workaround way to do it would be (in the controller methods)
var viewName = "Details"; // or whatever
ViewData["viewName"] = viewName;
return(View(viewName, customer));
and then in the partial itself, render it as
<input type="hidden" name="viewName"
value="<%=Html.Encode(ViewData["viewName"])%>" />
Question is - is there some property or syntax I can use to retrieve this directly instead of setting it from the controller? I've tried the obvious:
<input type="hidden" name="viewName"
value="<%=Html.Encode(this.Name)%>" />
but this doesn't work. What am I missing here?
Thanks.
Upvotes: 42
Views: 55838
Reputation: 1
you can try like this
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";
}
this will always return the ActionName
i use it like this
string actionName = context.HttpContext.Request.Headers["Referer"].ToString().GetViewFromUrl();
Upvotes: 0
Reputation: 1
You can use Razor:
in your View header
@{
ViewData["Title"] = "YourViewName";
}
in your View HTML
@{
var _nameCurrentView = ViewContext.ViewData["Title"];
}
use in your html the variable @_nameCurrentView
<li class="breadcrumb-item active">@_nameCurrentView</li>
or use in your action
ViewData["Title"]
Upvotes: 0
Reputation: 7117
If you are looking for solution for asp.net core you can use:
@System.IO.Path.GetFileNameWithoutExtension(ViewContext.View.Path)
This will return the current view name.
Upvotes: 4
Reputation: 4063
Easiest solution is using ViewBag.
public ActionResult Index()
{
ViewBag.CurrentView = "Index";
return View();
}
On the cshtml page
@{
var viewName = ViewBag.CurrentView;
}
Or,
((RazorView)ViewContext.View).ViewPath
Upvotes: 5
Reputation: 49
I had the same issue recently and the snippet of code I came up with solved my issue.
The only downfall is that Request.UrlReferrer could be null in some cases. Bit late but seemed to work for me and I covered all the bases of Request.UrlReferrer not being null.
if (Request.UrlReferrer != null)
{
var viewUrl = Request.UrlReferrer.ToString();
var actionResultName = viewUrl.Substring(viewUrl.LastIndexOf('/'));
var viewNameWithoutExtension = actionResultName.TrimStart('/');
}
Upvotes: 0
Reputation: 9584
Just wrote a blog thingy about this
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;
}
usage
<body class="<%= ViewContext.RouteString("{controller}_{action}") %>">
EDIT : Yes this is not going to give you the view name as the first comment states, it gives you the controller and action. But leaving it here as its valuable to know that it doesn't.
Upvotes: -3
Reputation: 22857
If you just want the action name then this would do the trick:
public static string ViewName(this HtmlHelper html)
{
return html.ViewContext.RouteData.GetRequiredString("action");
}
Upvotes: 9
Reputation: 59001
Well if you don't mind having your code tied to the specific view engine you're using, you can look at the ViewContext.View
property and cast it to WebFormView
var viewPath = ((WebFormView)ViewContext.View).ViewPath;
I believe that will get you the view name at the end.
EDIT: Haacked is absolutely spot-on; to make things a bit neater I've wrapped the logic up in an extension method like so:
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"));
}
}
}
which seems to do exactly what I was after.
Upvotes: 37
Reputation: 567
If you want to get the filename from within a partial view, this seems to work:
public static class HtmlHelperExtensions
{
public static string GetViewFileName(this HtmlHelper html, object view)
{
return @"\\"+ view.GetType().FullName.Replace("ASP._Page_", "").Replace("_cshtml", ".cshtml").Replace("_", @"\\");
}
}
And in the partial view, you should do something like this:
var filename = Html.GetViewFileName(this);
or this:
@Html.GetViewFileName(this)
Please do comment if this is not a good approach - any alternatives?
Upvotes: 4
Reputation: 50273
I had the same problem and that's how I solved it:
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
);
}
}
}
Then in the view:
var name = Html.CurrentViewName();
or simply
@Html.CurrentViewName()
Upvotes: 17
Reputation: 22760
Shouldn't you be using a validation method like Nerd Dinner implements?
That way you don't actually need to do all this and you can just return the View.
Upvotes: 0