我通常希望使用数据库中的内容呈现 ActionLink(想象一个 Id/Name 组合),因此我会将以下内容放入我的 View 中:
@foreach (var row in Model)
{
<li>@Html.ActionLink(row.Name, "Action", "Controller", new { id = row.Id })</li>
}
但是,如果名称为空字符串,则会引发异常。有什么办法可以防止这种情况发生吗?我想覆盖 ActionLink,但它是一个扩展,所以我无法覆盖。
有什么建议吗?
编辑:
首先,我不控制数据,否则我会确保“名称”字段是必填字段并且始终填充。不幸的是,这种情况并非如此。
其次,我意识到用户将没有任何可点击的内容,但我相信呈现空链接是比给他们 YSOD 更好的选择。
最佳答案
事实证明,实例方法始终优于具有相同签名的扩展方法。
我能够加载 CustomHtmlHelper 并将实例方法 ActionLink 方法放入新类中:
public abstract class CustomWebViewPage<T> : WebViewPage<T>
{
public new CustomHtmlHelper<T> Html { get; set; }
public override void InitHelpers()
{
Ajax = new AjaxHelper<T>(ViewContext, this);
Url = new UrlHelper(ViewContext.RequestContext);
//Load Custom Html Helper instead of Default
Html = new CustomHtmlHelper<T>(ViewContext, this);
}
}
HtmlHelper 如下(从 Reflector 复制的 ActionLink 方法,没有进行 LinkText 错误检查:
public class CustomHtmlHelper<T> : HtmlHelper<T>
{
public CustomHtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) :
base(viewContext, viewDataContainer)
{
}
//Instance methods will always be called instead of extension methods when both exist with the same signature...
public MvcHtmlString ActionLink(string linkText, string actionName)
{
return ActionLink(linkText, actionName, null, new RouteValueDictionary(), new RouteValueDictionary());
}
public MvcHtmlString ActionLink(string linkText, string actionName, object routeValues)
{
return ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary());
}
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName)
{
return ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(), new RouteValueDictionary());
}
public MvcHtmlString ActionLink(string linkText, string actionName, RouteValueDictionary routeValues)
{
return ActionLink(linkText, actionName, null, routeValues, new RouteValueDictionary());
}
public MvcHtmlString ActionLink(string linkText, string actionName, object routeValues, object htmlAttributes)
{
return ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public MvcHtmlString ActionLink(string linkText, string actionName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
{
return ActionLink(linkText, actionName, null, routeValues, htmlAttributes);
}
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
{
return ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(routeValues), AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
{
return MvcHtmlString.Create(GenerateLink(ViewContext.RequestContext, RouteCollection, linkText, null, actionName, controllerName, routeValues, htmlAttributes));
}
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, object htmlAttributes)
{
return ActionLink(linkText, actionName, controllerName, protocol, hostName, fragment, new RouteValueDictionary(routeValues), AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
{
return MvcHtmlString.Create(GenerateLink(ViewContext.RequestContext, RouteCollection, linkText, null, actionName, controllerName, protocol, hostName, fragment, routeValues, htmlAttributes));
}
}
最后,将 pageBaseType 设置为 Views/Web.config
文件以使用新的自定义 WebViewPage:
<system.web.webPages.razor>
...
<pages pageBaseType="Fully.Qualified.Namespace.CustomWebViewPage">
...
</pages>
</system.web.webPages.razor>
希望这对其他人有帮助。
关于asp.net-mvc - 如何重写 Html.ActionLink?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15952240/