【发布时间】:2015-03-08 12:50:15
【问题描述】:
我的站点中有一个视图,其中显示了我的应用程序的所有控制器及其操作方法:
操作方法:
public ActionResult GetAllController()
{
var controllers = typeof (MvcApplication).Assembly.GetTypes().Where(typeof (IController).IsAssignableFrom);
return View(controllers.ToList());
}
查看:
<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>
它就像一个魅力:
HomeController
Index
About
MainController
Index
Create
Edit
Delete
...
现在我想为控制器和操作方法显示另一个名称。为此,我创建了一个自定义属性:
public class DisplayNameAttribute : FilterAttribute
{
public string Title { get; set; }
public DisplayNameAttribute(string title)
{
this.Title = title;
}
}
所以在这种情况下,我只需为每个控制器或操作方法设置该属性,如下所示:
[DisplayName("Latest News")]
public ActionResult News()
{
return View();
}
在这种情况下,我创建了一个使用内部视图的扩展方法:
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;
}
所以在视图内部我使用这种方式来显示动作方法或控制器的标题:
@item.DisplayAttribute(p => p.Name)
但是当我运行应用程序时,我会得到这个错误:
{"Index was outside the bounds of the array."}
从这行代码抛出:
return ((DisplayNameAttribute)attr[0]).Title;
有什么想法吗?
【问题讨论】:
-
渲染出来的html是什么样子的?这可能是可用的前端吗?
-
很简单。您正在尝试引用不存在的数组中的索引,即 attr.Length 将为 0,但您要求获取 attr 数组中的第一项 - 没有第一项。始终在访问对象/数组之前对其进行验证。
-
您在操作中使用
ControllerName而不是DisplayName是不是错字?如果没有,那可能是你的问题。 -
另外,你可能应该从
Attribute而不是FilterAttribute派生你的属性,这样MVC就不会将它添加到过滤器管道中。 -
@jbutler483 正如我提到的结果是这个错误:
Index was outside the bounds of the array.
标签: c# asp.net-mvc custom-attributes