2013-03-08 32 views
3

我已經創建了一個Html幫助程序來編碼電子郵件地址以防止垃圾郵件。這是自動生成電子郵件鏈接時MarkdownSharp庫使用的相同技術。從編碼屬性文本中阻止TagBuilder.MergeAttribute

問題是,TagBuilder.MergeAttribute編碼斷開鏈接的屬性文本。是否有可能重寫此行爲或至少以另一種方式指定屬性。我知道我可以退回到只使用字符串連接或StringBuilder,但TabBuilder確實提供了許多好處,例如輕鬆地合併其他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(); 
    } 

回答

3

我不相信你的幫手會做任何有意義的事情來幫助減少垃圾郵件。當抓取工具使用HTML解析器時,他們看到解碼的字符串,而不是編碼的字符串。它與瀏覽器本身的邏輯相同。所以他們需要做的就是去掉mailto:前綴,他們現在有了原始的電子郵件地址。

如果你仍然希望追求這個,你必須使用字符串連接。 TagBuilder不適用於已經編碼的輸入。確保你編碼&,'和'字符,如果你走這條路線

+0

當我在我的瀏覽器中查看鏈接的源時,我得到了編碼的字符串*不*解碼的,所以我假設這如果抓取工具沒有使用解析器,它會是一樣的嗎? – 2013-03-10 12:26:39