I have a view in my site that displays all controller and its action methods of my application:
Action Method:
public ActionResult GetAllController()
{
var controllers = typeof (MvcApplication).Assembly.GetTypes().Where(typeof (IController).IsAssignableFrom);
return View(controllers.ToList());
}
View:
<ul>
@foreach (var item in Model)
{
<li>
@item.Name
<ul>
@foreach (var action in item.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(method => typeof(ActionResult).IsAssignableFrom(method.ReturnType)))
{
<li>action.Name</li>
}
</ul>
</li>
}
</ul>
It works like a charm:
HomeController
Index
About
MainController
Index
Create
Edit
Delete
...
Now I want to display another name for controllers and the action methods. for doing that I have created a custom attribute:
public class DisplayNameAttribute : FilterAttribute
{
public string Title { get; set; }
public DisplayNameAttribute(string title)
{
this.Title = title;
}
}
So in this case I just set that attribute for each of controllers or action methods like this:
[DisplayName("Latest News")]
public ActionResult News()
{
return View();
}
In this case I created an extension method for using inside views:
public static string DisplayAttribute<T>(this T obj, Expression<Func<T, string>> value)
{
var memberExpression = value.Body as MemberExpression;
var attr = memberExpression.Member.GetCustomAttributes(typeof(DisplayNameAttribute), true);
return ((DisplayNameAttribute)attr[0]).Title;
}
So inside view I'm using this way for displaying the title of action method or controller:
@item.DisplayAttribute(p => p.Name)
But when I run application I'll get this error:
{"Index was outside the bounds of the array."}
That throws from this line of code:
return ((DisplayNameAttribute)attr[0]).Title;
Any idea?
ControllerNameinstead ofDisplayNameon the action? If not, that's probably your issue.Attributeinstead ofFilterAttribute, so that MVC doesn't add it to the filter pipeline.Index was outside the bounds of the array.