0

I wish to display the current action of the controller on my MVC View in a human readable format.

I understand you can acquire the name of the current action through:
@ViewContext.Controller.ValueProvider.GetValue("action")
this returns e.g. 'Index' in the example below

What I am looking to do is something like:

[DisplayName=Resources.Overview]
public ActionResult Index()
{
    return View();
}

and then print that DisplayName on the page, some pseudo-code like:

@ViewContext.Controller.ValueProvider.GetValue("action").GetAttribute("DisplayName")
which would return 'Overview' from Resources

Is this possible?

2 Answers 2

3

You should first make a reflection to the method with Type.GetMethodInfo

string actionName = ViewContext.RouteData.Values["Action"]
MethodInfo method = type.GetMethod(actionName);
var attribute = method.GetCustomAttributes(typeof(DisplayNameAttribute), false);
if (attribute.Length > 0)
   actionName = ((DisplayNameAttribute)attribute[0]).DisplayName;
else 
   actionName = type.Name;   // fallback to the type name of the controller

And then you can pass the actionName to the View using something like

   ViewBag.name = actionName;

and then get the Viewbag variable from the view

Sign up to request clarification or add additional context in comments.

3 Comments

This seems exactly like what I need. One further question: Is it possible to use this dynamically inside the View itself? I can hardcore e.g. Type type = Type.GetType(HomeController); but is it possible to get the current controller's type? Type type = Type.GetType(ViewContext.RouteData.Values["Controller"]); does not seem to work. If I can get that line working I'd be set
I'd recommend creating a custom action filter where you'd put this code. You can make it global by adding it in FilterConfig.cs and then, assuming you've added the DisplayName attribute, that ViewBag member will be set to it.
I'm not sure I completely understand your proposition. I believe I'm going to use the above code in a shared layout and use @ViewContext.Controller.GetType() to get the type of the current controller
1

Why not just set the DisplayName inside the Viewbag and retrieve it in code, for every page that requires it?

For Example,

public ActionResult Index()
{
    Viewbag.DisplayName = 'Resources.Overview'
    return View();
}

then in any view that populates the DisplayName value, you can display it at the top with the following,

<head>
    @ViewBag.DisplayName
</head>

3 Comments

I have started to realise you actually want the action name specifically, so my method though it may work, wouldn't be without mess... i will leave it here, but you can disregard it if you dont like it :P
I've considered that, but I also want to do the same for my controller having a DisplayName and show both (and potentially even other data too which I could set on controller-level). Which would result in me having to copypaste the line e.g. ViewBag.ControllerDisplayName = Resources.Home on every single method. This inefficiency made me curious if there is a solution along the lines I'm thinking of.
Agreed, the implementation is easy, but its just messy!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.