tags:

views:

524

answers:

4

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.

+2  A: 

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

HTH, Dan

Daniel Elliott
then Html.ViewName() :)
Daniel Elliott
I need the View name, not the action name. The view isn't contained in the route data anywhere; it's determined by the return value from the controller method.
Dylan Beattie
A: 

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.

griegs
A: 

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}") %>">
Anthony Johnston
+6  A: 

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. Thanks Phil. :)

Haacked