你如何重写Html.ActionLink? [英] How do you override Html.ActionLink?

查看:360
本文介绍了你如何重写Html.ActionLink?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常会想渲染从数据库内容的ActionLink的(想象一个ID /名称组合),所以我会把我的观点如下:

Often I will want to render an ActionLink with content from the database (imagine an Id/Name combination) so I will put the following in my view:

        @foreach (var row in Model)
        {
            <li>@Html.ActionLink(row.Name, "Action", "Controller", new { id = row.Id })</li>
        }

不过,这如果名称为空字符串抛出一个异常。有没有什么办法prevent这一点。我想重写ActionLink的,但它是一个扩展,所以我不能覆盖。

However, this throws an exception if the Name is an empty string. Is there any way to prevent this. I would like to override ActionLink, but it is an extension so I cannot override.

有什么建议?

编辑:

首先,我不控制数据,否则我将确保名称字段是必需的,总是被填充。不幸的是这不是这种情况。

First, I do not control the data, or I would ensure that the Name field is required and always populated. Unfortunately this is not the case.

二,我意识到用户将没有什么可以点击,但我相信,呈现空链路比给他们YSOD一个更好的选择。

Second, I realize the user will have nothing to click on, but I believe that rendering an empty link is a better alternative than giving them a YSOD.

推荐答案

原来,实例方​​法总是会比pferred具有相同签名的扩展方法$ P $。

It turns out that an instance method will always be preferred over an extension method with the same signature.

我能够加载CustomHtmlHelper并把实例方法ActionLink的方法,在新的类:

I was able to load a CustomHtmlHelper and put instance method ActionLink methods in the new class:

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如下:从反射器复制未经连结文字错误校验(ActionLink的方法:

And the HtmlHelper is as follows (ActionLink methods copied from Reflector without the LinkText error check:

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的int 查看/ Web.config中文件,以使用新的自定义WebViewPage:

And finally, setting the pageBaseType int the Views/Web.config file to use the new custom WebViewPage:

  <system.web.webPages.razor>
    ...
    <pages pageBaseType="Fully.Qualified.Namespace.CustomWebViewPage">
    ...
    </pages>
  </system.web.webPages.razor>

希望这可以帮助其他人。

Hope this helps someone else.

这篇关于你如何重写Html.ActionLink?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆