C#代码处理前台html标签拼接

  之前一篇文章是写,JavaScript处理特殊字符拼接时截断问题。最近在处理公司老软件兼容性升级时碰到的一个类似的问题,这次是后台拼接字符串,前台.aspx页面显示的。中间走了两次弯路,在此记录一下。

先看个正确的效果图。C#代码处理前台html标签拼接

图(1)这个图看起来是不是有点眼熟

业务处理场景简单化一下。在日期控件里显示拼接的html标签。下面代码是未处理这个bug时源代码。

 1         StringBuilder strBld = new StringBuilder();
 2             CalendarDay day = e.Day;
 3             TableCell tc = e.Cell;
 4 
 5             if (day.IsOtherMonth)
 6             {
 7 
 8                 tc.Controls.Clear();
 9                 return;
10             }
11             e.Cell.Attributes.Remove("align");
12             e.Cell.Attributes.Add("align", "left");
13             e.Cell.CssClass = "date";
14 
15             strBld.AppendFormat("<dl><dt>");
16             strBld.Append(day.Date.Day.ToString() + "日");
17             strBld.Append("</dt>");
18             DataRow[] drs = dsNote.Tables[0].Select(" createDate>'" + day.Date.ToString() + "' and createDate<'" + day.Date.AddDays(1).ToString() + "'");
19             if (drs.Length > 0)
20             {
21                 strBld.Append("<dd><ul>");
22                 int num = 0;
23                 //获得数据
24                 foreach (DataRow dr in drs)
25                 {
26                     if (num < 3)
27                     {
28                         strBld.AppendFormat("<li><img src='../images/main/manage_ico.gif' /><a onclick='opendlg({1})' n title='{2}'>{0}</a></li>",
29                                       Globals.GetSummary(dr["title"].ToString(), 5),
30                                           dr["noteID"].ToString(), dr["title"].ToString());
31                     }
32                     else
33                     {
34                         strBld.AppendFormat("<li><a onclick='opendlg2(\"{0}\")'>更多....</a></li>", e.Day.Date.ToShortDateString());
35                         break;
36                     }
37                     num++;
38                 }
39                 strBld.Append("</ul></dd>");
40             }
41             strBld.Append("</dl>");
42             tc.Text = strBld.ToString();

  拼接的字符串,“<a onclick='opendlg({1})' n title='{2}'>” 这种形式会在输入特殊字符“'”单引号时截断,导致后面的内容显示错误。见下图。

C#代码处理前台html标签拼接

图(2)

  第一次解决思路(当时很天真:D):既然onclick里的opendlg()有用,那我直接在title里用上escapeHtml这个方法就是了。结果并没什么用。页面直接显示出来这个方法o(╯□╰)o。

C#代码处理前台html标签拼接

图(3)

  第二种思路是用Server.HtmlEncode()。代码30行dr["title"].ToString()这个参数用Server.HtmlEncode()包起来,满心期待的能奏效,结果还是不行,且希望越大,失望越大,日历表格整个都显示不全了。

C#代码处理前台html标签拼接

图(4)

  最后还是html实体编码的思路,只不过这次是换后台执行。用两个方法处理了下特殊字符。用HtmlEncode(string s)方法替代了Server.HtmlEncode(),解决问题。下面贴上代码:

        public string HtmlEncode(string s)
        {
            if (s == null)
            {
                return null;
            }
            StringBuilder sb = new StringBuilder();
            StringWriter output = new StringWriter(sb);
            HtmlEncode(s, output);
            return sb.ToString();
        }


        public void HtmlEncode(string s, TextWriter output)
        {
            if (s != null)
            {
                int length = s.Length;
                for (int i = 0; i < length; i++)
                {
                    char ch = s[i];
                    char ch2 = ch;
                    if (ch2 != '"')
                    {
                        switch (ch2)
                        {
                            case '<':
                                output.Write("&lt;");
                                continue;
                            case '>':
                                output.Write("&gt;");
                                continue;
                            case '\'':
                                output.Write("&#39;");
                                continue;
                            case '&':
                                output.Write("&amp;");
                                continue;
                            default:
                                output.Write(ch);
                                continue;
                        }
                    }
                    else
                    {
                        output.Write("&quot;");
                        continue;
                    }
                }
            }
        }
View Code