3

スパムを防ぐために、電子メール アドレスをエンコードする Html ヘルパーを作成しました。これは、電子メール リンクを自動生成するときに MarkdownSharp ライブラリで使用される手法と同じです。

問題はTagBuilder.MergeAttribute、リンクを壊す属性テキストをエンコードすることです。この動作をオーバーライドするか、少なくとも別の方法で属性を指定することは可能ですか? 文字列連結または a を使用するだけにフォールバックできることはわかっていますStringBuilderTabBuilder、他の 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

あなたのヘルパーがスパムを減らすのに役立つことをするとは思えません。クローラーが HTML パーサーを使用すると、エンコードされた文字列ではなく、デコードされた文字列が表示されます。これは、ブラウザ自体と同じロジックです。そのため、mailto: プレフィックスを削除するだけで、元のメール アドレスを取得できます。

それでもこれを追求したい場合は、文字列連結を使用する必要があります。TagBuilder は、既にエンコードされている入力を操作するようには設計されていません。このルートを使用する場合は、必ず &、'、および " 文字をエンコードしてください。

于 2013-03-09T21:07:19.010 に答える