3

我创建了一个对电子邮件地址进行编码的 Html 助手,以防止垃圾邮件。这与 MarkdownSharp 库在自动生成电子邮件链接时使用的技术相同。

问题是对TagBuilder.MergeAttribute破坏链接的属性文本进行编码。是否可以覆盖此行为或至少以另一种方式指定属性。我知道我可以回退到仅使用字符串连接或 aStringBuilderTabBuilder确实提供了许多好处,例如轻松合并其他 HTML 属性。

    /// <summary>
    /// Creates an encoded email link in the hopes of foiling most SPAM bots
    /// </summary>
    public static IHtmlString EmailLink(this HtmlHelper html, string email, string text = null, object htmlAttributes = null)
    {
        Ensure.Argument.NotNullOrEmpty(email, "email");

        var encodedEmail = EncodeEmailAddress(email);

        var tb = new TagBuilder("a");
        tb.MergeAttribute("href", "mailto:" + encodedEmail);

        tb.InnerHtml = text ?? encodedEmail;

        if (htmlAttributes != null)
        {
            tb.MergeAttributes(new RouteValueDictionary(htmlAttributes));
        }

        return new HtmlString(tb.ToString());
    }

    /// <summary>
    /// encodes email address randomly  
    /// roughly 10% raw, 45% hex, 45% dec 
    /// note that @ is always encoded and : never is
    /// </summary>
    private static string EncodeEmailAddress(string addr)
    {
        var sb = new StringBuilder(addr.Length * 5);
        var rand = new Random();
        int r;
        foreach (char c in addr)
        {
            r = rand.Next(1, 100);
            if ((r > 90 || c == ':') && c != '@')
                sb.Append(c);                         // m
            else if (r < 45)
                sb.AppendFormat("&#x{0:x};", (int)c); // &#x6D
            else
                sb.AppendFormat("&#{0};", (int)c);    // &#109
        }
        return sb.ToString();
    }
4

1 回答 1

3

I do not believe your helper will do anything meaningful to help reduce spam. When crawlers use HTML parsers, they're seeing the decoded strings, not the encoded ones. It is the same logic as in the browser itself. So all they need to do is strip the mailto: prefix, and they now have the original email address.

If you still wish to pursue this, you must use string concatenation. TagBuilder isn't designed to work with input that is already encoded. Make sure that you encode the &, ', and " characters if you go this route.

于 2013-03-09T21:07:19.010 回答