<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.darkthread.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>黑暗執行緒 : CODE, ASP.NET</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/ASP.NET/default.aspx</link><description>Tags: CODE, ASP.NET</description><dc:language>zh-CHT</dc:language><generator>CommunityServer 2007.1 (Debug Build: 20917.1142)</generator><item><title>MicroHttpServer - 用100行C#寫一個HTTP Server</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/08/14/macro-http-server.aspx</link><pubDate>Sat, 14 Aug 2010 00:23:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6827</guid><dc:creator>Jeffrey</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=6827</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/08/14/macro-http-server.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;有個點子，想在WinForm上跑程式模擬出Web Server功能，讓Browser或程式可以透過HTTP協定與其溝通。既然想到，就動手做看看囉!&lt;/p&gt;  &lt;p&gt;HTTP Server絕大部分的核心功能，其實都可用.NET搞定: 用&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.aspx"&gt;TcpListener&lt;/a&gt;接受特定Port連入的TCP連線，取得&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.aspx"&gt;NetworkStream&lt;/a&gt;，以StreamReader、StreamWriter讀取及寫入資料... &lt;a href="http://en.wikipedia.org/wiki/Base_Class_Library"&gt;.NET BCL&lt;/a&gt;真是應有盡有!相較之下，以前那種基礎元件跟函式庫都得自己張羅的時代，只能用茹毛飲血來形容。&lt;/p&gt;  &lt;p&gt;有了BCL的加持，配合兩個自訂類別封裝Request、Response，只花了不到100行C#，就組出一個可以接受HTTP Request，傳回結果的超迷你HTTP Server! &lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Net;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Net.Sockets;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Threading;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DarkHttpServer&lt;/pre&gt;

    &lt;pre class="alt"&gt;{&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//Reuquest物件&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CompactRequest&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Method, Url, Protocol;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Headers;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//傳入StreamReader，讀取Request傳入的內容&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; CompactRequest(StreamReader sr)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="rem"&gt;//第一列格式如: GET /index.html HTTP/1.1&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; firstLine = sr.ReadLine();&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt;[] p = firstLine.Split(&lt;span class="str"&gt;&amp;#39; &amp;#39;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            Method = p[0];&lt;/pre&gt;

    &lt;pre&gt;            Url = (p.Length &amp;gt; 1) ? p[1] : &lt;span class="str"&gt;&amp;quot;NA&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            Protocol = (p.Length &amp;gt; 2) ? p[2] : &lt;span class="str"&gt;&amp;quot;NA&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="rem"&gt;//讀取其他Header，格式為HeaderName: HeaderValue&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; line = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            Headers = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;while&lt;/span&gt; (!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(line = sr.ReadLine()))&lt;/pre&gt;

    &lt;pre&gt;            {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;int&lt;/span&gt; pos = line.IndexOf(&lt;span class="str"&gt;&amp;quot;:&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (pos &amp;gt; -1)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    Headers.Add(line.Substring(0, pos),&lt;/pre&gt;

    &lt;pre&gt;                        line.Substring(pos + 1));&lt;/pre&gt;

    &lt;pre class="alt"&gt;            }&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//Response物件&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CompactResponse&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//預設200, 404, 500三種回應&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; HttpStatus&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Http200 = &lt;span class="str"&gt;&amp;quot;200 OK&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Http404 = &lt;span class="str"&gt;&amp;quot;404 Not Found&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Http500 = &lt;span class="str"&gt;&amp;quot;500 Error&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; StatusText = HttpStatus.Http200;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ContentType = &lt;span class="str"&gt;&amp;quot;text/plain&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="rem"&gt;//可回傳Response Header&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Headers&lt;/pre&gt;

    &lt;pre&gt;            = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//傳回內容，以byte[]表示&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] Data = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] { };&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//簡陋但堪用的HTTP Server&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MicroHttpServer&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; Thread serverThread;&lt;/pre&gt;

    &lt;pre&gt;        TcpListener listener;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//呼叫端要準備一個函數，接收CompactRequest，回傳CompactResponse&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; MicroHttpServer(&lt;span class="kwrd"&gt;int&lt;/span&gt; port,&lt;/pre&gt;

    &lt;pre class="alt"&gt;            Func&amp;lt;CompactRequest, CompactResponse&amp;gt; reqProc)&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            IPAddress ipAddr = IPAddress.Parse(&lt;span class="str"&gt;&amp;quot;127.0.0.1&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;            listener = &lt;span class="kwrd"&gt;new&lt;/span&gt; TcpListener(ipAddr, port);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//另建Thread執行&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;            serverThread = &lt;span class="kwrd"&gt;new&lt;/span&gt; Thread(() =&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            {&lt;/pre&gt;

    &lt;pre&gt;                listener.Start();&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;while&lt;/span&gt; (&lt;span class="kwrd"&gt;true&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;                {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    Socket s = listener.AcceptSocket();&lt;/pre&gt;

    &lt;pre&gt;                    NetworkStream ns = &lt;span class="kwrd"&gt;new&lt;/span&gt; NetworkStream(s);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    &lt;span class="rem"&gt;//解讀Request內容&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;                    StreamReader sr = &lt;span class="kwrd"&gt;new&lt;/span&gt; StreamReader(ns);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    CompactRequest req = &lt;span class="kwrd"&gt;new&lt;/span&gt; CompactRequest(sr);&lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="rem"&gt;//呼叫自訂的處理邏輯，得到要回傳的Response&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    CompactResponse resp = reqProc(req);&lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="rem"&gt;//傳回Response&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    StreamWriter sw = &lt;span class="kwrd"&gt;new&lt;/span&gt; StreamWriter(ns);&lt;/pre&gt;

    &lt;pre&gt;                    sw.WriteLine(&lt;span class="str"&gt;&amp;quot;HTTP/1.1 {0}&amp;quot;&lt;/span&gt;, resp.StatusText);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    sw.WriteLine(&lt;span class="str"&gt;&amp;quot;Content-Type: &amp;quot;&lt;/span&gt; + resp.ContentType);&lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; k &lt;span class="kwrd"&gt;in&lt;/span&gt; resp.Headers.Keys)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                        sw.WriteLine(&lt;span class="str"&gt;&amp;quot;{0}: {1}&amp;quot;&lt;/span&gt;, k, resp.Headers[k]);&lt;/pre&gt;

    &lt;pre&gt;                    sw.WriteLine(&lt;span class="str"&gt;&amp;quot;Content-Length: {0}&amp;quot;&lt;/span&gt;, resp.Data.Length);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    sw.WriteLine();&lt;/pre&gt;

    &lt;pre&gt;                    sw.Flush();&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    &lt;span class="rem"&gt;//寫入資料本體&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;                    s.Send(resp.Data);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    &lt;span class="rem"&gt;//結束連線&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;                    s.Shutdown(SocketShutdown.Both);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    ns.Close();&lt;/pre&gt;

    &lt;pre&gt;                }&lt;/pre&gt;

    &lt;pre class="alt"&gt;            });&lt;/pre&gt;

    &lt;pre&gt;            serverThread.Start();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Stop()&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            listener.Stop();&lt;/pre&gt;

    &lt;pre class="alt"&gt;            serverThread.Abort();&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;好了，有了MicroHttpServer類別，我們來寫一個小小的Console Application，做一個&lt;font color="#ff8000"&gt;將特定目錄下JPG圖檔以網頁方式呈現&lt;/font&gt;的迷你Web Server當作應用範例:&lt;/p&gt;

&lt;div class="BlogCodeBlock"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;

    &lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; DarkHttpServer&lt;/pre&gt;

    &lt;pre&gt;{&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; path = &lt;span class="str"&gt;@&amp;quot;C:\temp\arts&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            MicroHttpServer mhs = &lt;span class="kwrd"&gt;new&lt;/span&gt; MicroHttpServer(1688,&lt;/pre&gt;

    &lt;pre&gt;            (req) =&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;            {&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (req.Url == &lt;span class="str"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; ListPhoto(req);&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (req.Url.EndsWith(&lt;span class="str"&gt;&amp;quot;.jpg&amp;quot;&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; GetJpeg(&lt;/pre&gt;

    &lt;pre&gt;                        Path.Combine(path, req.Url.TrimStart(&lt;span class="str"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;)));&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CompactResponse()&lt;/pre&gt;

    &lt;pre&gt;                {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    StatusText = CompactResponse.HttpStatus.Http500&lt;/pre&gt;

    &lt;pre&gt;                };&lt;/pre&gt;

    &lt;pre class="alt"&gt;            });&lt;/pre&gt;

    &lt;pre&gt;            Console.Write(&lt;span class="str"&gt;&amp;quot;Press any key to stop...&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            Console.Read();&lt;/pre&gt;

    &lt;pre&gt;            mhs.Stop();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//列出圖檔，組成網頁傳回&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; CompactResponse ListPhoto(CompactRequest req)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            StringBuilder sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;

    &lt;pre class="alt"&gt;            sb.Append(&lt;span class="str"&gt;@&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Index&amp;lt;/title&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;lt;style type=&amp;#39;text/css&amp;#39;&amp;gt;img { &lt;/pre&gt;

    &lt;pre&gt;    width: 160px; height: 120px; float: left;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    margin: 10px;&lt;/pre&gt;

    &lt;pre&gt;}&amp;lt;/style&amp;gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;&amp;quot;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            sb.Append(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; file &lt;span class="kwrd"&gt;in&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                Directory.GetFiles(path, &lt;span class="str"&gt;&amp;quot;*.jpg&amp;quot;&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre&gt;                sb.AppendFormat(&lt;span class="str"&gt;&amp;quot;&amp;lt;img src=&amp;#39;{0}&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    Path.GetFileName(file));&lt;/pre&gt;

    &lt;pre&gt;            sb.Append(&lt;span class="str"&gt;&amp;quot;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CompactResponse()&lt;/pre&gt;

    &lt;pre&gt;            {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                ContentType = &lt;span class="str"&gt;&amp;quot;text/html&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;                Data = Encoding.UTF8.GetBytes(sb.ToString())&lt;/pre&gt;

    &lt;pre class="alt"&gt;            };&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//取得圖檔&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; CompactResponse GetJpeg(&lt;span class="kwrd"&gt;string&lt;/span&gt; file)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (File.Exists(file))&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CompactResponse()&lt;/pre&gt;

    &lt;pre&gt;                {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    ContentType = &lt;span class="str"&gt;&amp;quot;image/jpeg&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;                    Data = File.ReadAllBytes(file)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                };&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="rem"&gt;//找不到檔案時傳回HTTP 404&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CompactResponse()&lt;/pre&gt;

    &lt;pre&gt;                {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    StatusText = CompactResponse.HttpStatus.Http404&lt;/pre&gt;

    &lt;pre&gt;                };&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;用IE連上httq://localhost:1688，薑薑薑薑! 小閃光的&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/08/07/2010-summer-arts.aspx"&gt;手工藝品&lt;/a&gt;在他爹的&amp;quot;&lt;font color="#00ff00"&gt;手工藝品&lt;/font&gt;&amp;quot;上被展示出來了。(這證明我的手也很巧呀! XD)&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6826/500x375.aspx" class="PopBoxImageSmall" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;請大家跟我一起高呼:&lt;font size="3" color="#00ff00"&gt; &lt;font color="#ff8000"&gt;.NET好威呀!&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6827" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>筆記-讓ASP.NET TreeView可以透過Javascript新增節點</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/07/16/add-node-to-asp-net-treeview.aspx</link><pubDate>Fri, 16 Jul 2010 08:13:40 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6682</guid><dc:creator>Jeffrey</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=6682</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/07/16/add-node-to-asp-net-treeview.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;同事在網頁上用了&lt;a href="http://msdn.microsoft.com/zh-tw/library/d4fz6xk2(VS.80).aspx"&gt;ASP.NET TreeView控件&lt;/a&gt;，但專案規格中需要由Javascript端完成新增節點的動作，很不幸地，這不是ASP.NET TreeView內建支援的功能。&lt;/p&gt; &lt;p&gt;如果時間充裕的話，我會建議改用jQuery TreeView Plugin，較符合大量Client端客製的需求，但因時程迫在眉睫，且只差這個小功能，所以大家不要考究&amp;quot;破解&amp;quot;ASP.NET TreeView前端設計的意義，把它想像成打破水缸救人就好。&lt;/p&gt; &lt;p&gt;寫完這段程式，等同於小小地破解ASP.NET TreeView前端HTML與Script設計。發現原來每一個節點都是一個Table(選擇用Table來配置排列而沒用CSS，應是著眼於相容性，至於要相容誰相信大家心裡有數，讓我們一起吶喊&amp;quot;IE6退散&amp;quot;吧!)，其下的子節點則被包在一個DIV中。比較複雜的部分是前方的連接線圖示，圖檔是以&lt;a href="http://support.microsoft.com/kb/910442/en-us"&gt;Web Resource方式&lt;/a&gt;存在，所以URL難以預測，幸好有個TreeView1_ImageArray的字串函數記載了所有圖示的URL，可用Index去找出特定圖示。&lt;/p&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6679/original.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;不過要考慮節點所在位置不同，有時要用L型，有時要用├，有時要補空白，有時要補直線，麻煩的很，這部分花了不少Code處理。&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; AutoEventWireup=&amp;quot;true&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/C#&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!IsPostBack)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            TreeNode root = &lt;span class="kwrd"&gt;new&lt;/span&gt; TreeNode(&lt;span class="str"&gt;&amp;quot;Root&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            root.ChildNodes.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; TreeNode(&lt;span class="str"&gt;&amp;quot;Catg1&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;            root.ChildNodes.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; TreeNode(&lt;span class="str"&gt;&amp;quot;Catg2&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre&gt;            TreeNode node = &lt;span class="kwrd"&gt;new&lt;/span&gt; TreeNode(&lt;span class="str"&gt;&amp;quot;Catg3&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            node.ChildNodes.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; TreeNode(&lt;span class="str"&gt;&amp;quot;ItemX&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre&gt;            root.ChildNodes.Add(node);&lt;/pre&gt;&lt;pre class="alt"&gt;            root.ChildNodes.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; TreeNode(&lt;span class="str"&gt;&amp;quot;Catg4&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre&gt;            SetTreeNodeLink(root);&lt;/pre&gt;&lt;pre class="alt"&gt;            TreeView1.Nodes.Add(root);&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetTreeNodeLink(TreeNode node)&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        node.NavigateUrl = &lt;span class="str"&gt;&amp;quot;BLOCKED SCRIPTselNode(&amp;#39;&amp;quot;&lt;/span&gt; + node.Text + &lt;span class="str"&gt;&amp;quot;&amp;#39;);void(0);&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (TreeNode child &lt;span class="kwrd"&gt;in&lt;/span&gt; node.ChildNodes)&lt;/pre&gt;&lt;pre&gt;            SetTreeNodeLink(child);&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;lt;html xmlns=&lt;span class="str"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;head runat=&lt;span class="str"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;title&amp;gt;TreeView Client Script&amp;lt;/title&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;script src=&lt;span class="str"&gt;&amp;quot;http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.js&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        $(&lt;span class="kwrd"&gt;function&lt;/span&gt; () {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;//選取節點時觸發&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            window.selNode = &lt;span class="kwrd"&gt;function&lt;/span&gt; (t) { $(&lt;span class="str"&gt;&amp;quot;#dvSelNode&amp;quot;&lt;/span&gt;).text(t); };&lt;/pre&gt;&lt;pre&gt;            $(&lt;span class="str"&gt;&amp;quot;#btnAdd&amp;quot;&lt;/span&gt;).click(&lt;span class="kwrd"&gt;function&lt;/span&gt; () {&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="rem"&gt;//註: 此處不考慮父節點名重覆及txtName特殊字元問題&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                addNode($(&lt;span class="str"&gt;&amp;quot;#dvSelNode&amp;quot;&lt;/span&gt;).text(), $(&lt;span class="str"&gt;&amp;quot;#txtName&amp;quot;&lt;/span&gt;).val(),&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="str"&gt;&amp;quot;BLOCKED SCRIPTselNode(&amp;#39;&amp;quot;&lt;/span&gt; + $(&lt;span class="str"&gt;&amp;quot;#txtName&amp;quot;&lt;/span&gt;).val() + &lt;span class="str"&gt;&amp;quot;&amp;#39;);void(0);&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            });&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; tvName = &lt;span class="str"&gt;&amp;quot;TreeView1&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; $tv = $(&lt;span class="str"&gt;&amp;quot;#&amp;quot;&lt;/span&gt; + tvName);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//Icon Url&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; tvIcons = window[tvName + &lt;span class="str"&gt;&amp;quot;_ImageArray&amp;quot;&lt;/span&gt;];&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//傳回連接線Icon&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;function&lt;/span&gt; genTreeViewIcon(i) {&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;&amp;lt;img style=&amp;#39;border-width: 0px;&amp;#39; src=&amp;#39;&amp;quot;&lt;/span&gt; +&lt;/pre&gt;&lt;pre&gt;                       tvIcons[i] + &lt;span class="str"&gt;&amp;quot;&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;//查出連接線Icon的索引值，有時要用相對順序算出展開收合狀態的Icon&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;function&lt;/span&gt; getTreeViewIconIndex(imgUrl) {&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; i = 0; i &amp;lt; tvIcons.length; i++)&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (tvIcons[i].length &amp;gt; 0 &amp;amp;&amp;amp; &lt;/pre&gt;&lt;pre&gt;                        imgUrl.indexOf(tvIcons[i]) &amp;gt; -1) &lt;span class="kwrd"&gt;return&lt;/span&gt; i;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; -1;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//加入新節點&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;function&lt;/span&gt; addNode(parentNodeText, nodeText, nodeLink) {&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="rem"&gt;//先找到Table&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;var&lt;/span&gt; $pt = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;                $tv.find(&lt;span class="str"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;).each(&lt;span class="kwrd"&gt;function&lt;/span&gt; () {&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.innerHTML == parentNodeText) {&lt;/pre&gt;&lt;pre class="alt"&gt;                        $pt = $(&lt;span class="kwrd"&gt;this&lt;/span&gt;).closest(&lt;span class="str"&gt;&amp;quot;table&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;                    }&lt;/pre&gt;&lt;pre&gt;                });&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; ($pt) {&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="rem"&gt;//找出目前節點的名稱&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; nodeId = $pt.find(&lt;span class="str"&gt;&amp;quot;a:last&amp;quot;&lt;/span&gt;).attr(&lt;span class="str"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; childBlockId = nodeId.replace(&lt;span class="str"&gt;&amp;quot;t&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;n&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="rem"&gt;//檢查是否已有Child, 若無則加上子節點div&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!$pt.next().&lt;span class="kwrd"&gt;is&lt;/span&gt;(&lt;span class="str"&gt;&amp;quot;div&amp;quot;&lt;/span&gt;)) {&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="rem"&gt;//找到前方的圖示&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="kwrd"&gt;var&lt;/span&gt; $pfxTd = $pt.find(&lt;span class="str"&gt;&amp;quot;td&amp;quot;&lt;/span&gt;).eq(-2);&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;var&lt;/span&gt; imgUrl = $pfxTd.find(&lt;span class="str"&gt;&amp;quot;img&amp;quot;&lt;/span&gt;).attr(&lt;span class="str"&gt;&amp;quot;src&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="rem"&gt;//Icon索引+2可換算出可展開的Icon&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                        $pfxTd.html(&lt;/pre&gt;&lt;pre&gt;                            &lt;span class="str"&gt;&amp;quot;&amp;lt;a id=&amp;#39;&amp;quot;&lt;/span&gt; + childBlockId + &lt;/pre&gt;&lt;pre class="alt"&gt;                            &lt;span class="str"&gt;&amp;quot;&amp;#39; href=\&amp;quot;BLOCKED SCRIPTTreeView_ToggleNode(&amp;quot;&lt;/span&gt; + tvName + &lt;span class="str"&gt;&amp;quot;_Data,&amp;quot;&lt;/span&gt; +&lt;/pre&gt;&lt;pre&gt;                            nodeId.substr(nodeId.lastIndexOf(&lt;span class="str"&gt;&amp;quot;t&amp;quot;&lt;/span&gt;) + 1, 3) + &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                            + childBlockId + &lt;span class="str"&gt;&amp;quot;,&amp;#39;t&amp;#39;,&amp;quot;&lt;/span&gt; + childBlockId + &lt;span class="str"&gt;&amp;quot;Nodes)\&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt; +&lt;/pre&gt;&lt;pre&gt;                            genTreeViewIcon(getTreeViewIconIndex(imgUrl) + 2) +&lt;/pre&gt;&lt;pre class="alt"&gt;                            &lt;span class="str"&gt;&amp;quot;&amp;lt;/a&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;                        $pt.after(&lt;span class="str"&gt;&amp;quot;&amp;lt;div id=&amp;#39;&amp;quot;&lt;/span&gt; + childBlockId + &lt;span class="str"&gt;&amp;quot;Nodes&amp;#39; style=&amp;#39;display: block&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;                    }&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; $childBlock = $pt.next();&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="rem"&gt;//計算新Node的流水號&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; maxSn = $tv.find(&lt;span class="str"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;).length + 1;&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; newNodeId = nodeId.substr(0, nodeId.lastIndexOf(&lt;span class="str"&gt;&amp;quot;t&amp;quot;&lt;/span&gt;) + 1) + maxSn;&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="rem"&gt;//以自己為複製藍本，重點要多加一格後縮&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; $npt = $pt.clone();&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="rem"&gt;//設定節點新值&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                    $npt.find(&lt;span class="str"&gt;&amp;quot;a:last&amp;quot;&lt;/span&gt;).attr(&lt;span class="str"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;, newNodeId).attr(&lt;span class="str"&gt;&amp;quot;href&amp;quot;&lt;/span&gt;, nodeLink).text(nodeText);&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="rem"&gt;//處理連接線&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; $cell = $npt.find(&lt;span class="str"&gt;&amp;quot;td&amp;quot;&lt;/span&gt;).eq(-2);&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; imgUrl = $cell.find(&lt;span class="str"&gt;&amp;quot;img&amp;quot;&lt;/span&gt;).attr(&lt;span class="str"&gt;&amp;quot;src&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; idx = getTreeViewIconIndex(imgUrl);&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (idx &amp;gt;= 11 &amp;amp;&amp;amp; idx &amp;lt;= 13) idx = 6; &lt;span class="kwrd"&gt;else&lt;/span&gt; idx = 3;&lt;/pre&gt;&lt;pre class="alt"&gt;                    $cell.html(genTreeViewIcon(idx)) &lt;span class="rem"&gt;//改連接線&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                    .after(&lt;span class="str"&gt;&amp;quot;&amp;lt;td&amp;gt;&amp;quot;&lt;/span&gt; + genTreeViewIcon(13) + &lt;span class="str"&gt;&amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; ($childBlock.children().length &amp;gt; 0) {&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="rem"&gt;//如果已有其他兄弟節點，要改最後一筆兄弟節點的連接線&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;var&lt;/span&gt; $lastItem = $childBlock.children(&lt;span class="str"&gt;&amp;quot;table&amp;quot;&lt;/span&gt;).last();&lt;/pre&gt;&lt;pre&gt;                        $cell = $lastItem.find(&lt;span class="str"&gt;&amp;quot;td&amp;quot;&lt;/span&gt;).eq(-2);&lt;/pre&gt;&lt;pre class="alt"&gt;                        ($cell.children(&lt;span class="str"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;).length ? $cell.children(&lt;span class="str"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;) : $cell)&lt;/pre&gt;&lt;pre&gt;                        .html(genTreeViewIcon(&lt;/pre&gt;&lt;pre class="alt"&gt;                            getTreeViewIconIndex($cell.find(&lt;span class="str"&gt;&amp;quot;img&amp;quot;&lt;/span&gt;).attr(&lt;span class="str"&gt;&amp;quot;src&amp;quot;&lt;/span&gt;)) - 3));&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="rem"&gt;//若兄弟節點已有子節點也要改其連接線(實在有夠麻煩)&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;if&lt;/span&gt; ($lastItem.next().&lt;span class="kwrd"&gt;is&lt;/span&gt;(&lt;span class="str"&gt;&amp;quot;div&amp;quot;&lt;/span&gt;)) {&lt;/pre&gt;&lt;pre&gt;                            &lt;span class="kwrd"&gt;var&lt;/span&gt; tdIdx = $lastItem.find(&lt;span class="str"&gt;&amp;quot;td&amp;quot;&lt;/span&gt;).length - 2;&lt;/pre&gt;&lt;pre class="alt"&gt;                            $lastItem.next().children().each(&lt;span class="kwrd"&gt;function&lt;/span&gt; () {&lt;/pre&gt;&lt;pre&gt;                                $(&lt;span class="kwrd"&gt;this&lt;/span&gt;).find(&lt;span class="str"&gt;&amp;quot;td:eq(&amp;quot;&lt;/span&gt; + tdIdx + &lt;span class="str"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;).html(&lt;/pre&gt;&lt;pre class="alt"&gt;                                    genTreeViewIcon(6) &lt;span class="rem"&gt;//直線&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                                );&lt;/pre&gt;&lt;pre class="alt"&gt;                            });&lt;/pre&gt;&lt;pre&gt;                        }&lt;/pre&gt;&lt;pre class="alt"&gt;                    }&lt;/pre&gt;&lt;pre&gt;                    $childBlock.append($npt);&lt;/pre&gt;&lt;pre class="alt"&gt;                }&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; h = [];&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; i = 0; i &amp;lt; TreeView1_ImageArray.length; i++) {&lt;/pre&gt;&lt;pre class="alt"&gt;                h.push(&lt;span class="str"&gt;&amp;quot;&amp;lt;span&amp;gt;&amp;quot;&lt;/span&gt; + i + genTreeViewIcon(i) + &lt;span class="str"&gt;&amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            $(&lt;span class="str"&gt;&amp;quot;#dvDisp&amp;quot;&lt;/span&gt;).html(h.join(&lt;span class="str"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre&gt;        });&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;form1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;dvDisp&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;dvSelNode&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Not Selected&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;txtName&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;button&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;btnAdd&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Add&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:TreeView&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;TreeView1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;250px&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ShowLines&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;True&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;320px&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:TreeView&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;以上是程式，我當救人兼練功，各位有興趣隨便看看，沒什麼大用。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6682" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>CODE-自動產生對應Javascript物件的.NET類別</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/06/06/json-reflected-class-codegen.aspx</link><pubDate>Sat, 05 Jun 2010 22:01:14 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6497</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=6497</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/06/06/json-reflected-class-codegen.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;&lt;strong&gt;Abstract&lt;/strong&gt;: This is a code generator to declare reflected .NET class of Javascript object using JSON.NET JObject features.&lt;/p&gt;  &lt;p&gt;這是跟同事在討論系統架構時冒出的議題...&lt;/p&gt;  &lt;p&gt;網頁前端將使用者輸入結果組裝成結構單純的Javascript物件，一個欄位對應一個屬性，但有些欄位如電話、地址等可能有多筆，故屬性型別除了字串、數字外，也有會有電話號碼物件陣列，電話號碼物件則包含國碼、區碼、號碼三個屬性。組裝完成的Javascript透過JSON.stringify會以字串形式傳至後端，針對這種前端動態組成的JSON，我們可在後端沒有事先宣告對應.NET Class的狀況下，將其反序列化成JSON.NET的JObject物件，再透過JObject.Properties探索其中的細節，這就是&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/06/05/json-net-jobject-example.aspx"&gt;昨天文章&lt;/a&gt;試圖展示的重點。&lt;/p&gt;  &lt;p&gt;不過，如果我還是想在寫.NET Code時享受美妙Intellisense，讓我輸入屬性名稱可以少打幾個字，並明確知道屬性類別；而當我豬頭打錯屬性名稱時，也很渴望Visual Studio直接在錯字下方餵我吃一條紅蚯蚓...&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6495/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;嗯，要怎麼收獲先怎麼裁，我們唯一的選擇就是乖乖在Server-Side把對應Javascript物件的.NET類別宣告出來，才能享有這一切。那就看著Javascript物件規格，認命地靠手工把一個個屬性打上去吧... 等等! 若只能乖乖打字修行，又何來此文? &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;font color="#ff8000"&gt;&lt;strong&gt;是的，我又想偷懶了!!&lt;/strong&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;想要享受Intellisense又不甘願打字，所以我試寫了一個自動依Javascript物件規格建立對應.NET Class的程式碼產生器。以下是個簡單示範，網頁上有兩個TextArea，上方放JSON字串，下方則是分析JSON字串後產生的.NET類別宣告程式碼。&lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;JSON 2 Class&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;jquery-1.4.2.js&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;        $(&lt;span class="kwrd"&gt;function&lt;/span&gt; () {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; ($(&lt;span class="str"&gt;&amp;quot;#txtJson&amp;quot;&lt;/span&gt;).val() == &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;) {&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;var&lt;/span&gt; obj = {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    Name: &lt;span class="str"&gt;&amp;quot;Jeffrey&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;                    RegTime: &lt;span class="kwrd"&gt;new&lt;/span&gt; Date(),&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    Level: 99,&lt;/pre&gt;

    &lt;pre&gt;                    Records: [1024, 9999, 32767],&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    Rank: { Code: &lt;span class="str"&gt;&amp;quot;DKNT&amp;quot;&lt;/span&gt;, Name: &lt;span class="str"&gt;&amp;quot;DarkNight&amp;quot;&lt;/span&gt; },&lt;/pre&gt;

    &lt;pre&gt;                    Skills: [&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    { Name: &lt;span class="str"&gt;&amp;quot;Sword&amp;quot;&lt;/span&gt;, Level: 1 },&lt;/pre&gt;

    &lt;pre&gt;                    { Name: &lt;span class="str"&gt;&amp;quot;Steal&amp;quot;&lt;/span&gt;, Level: 2 },&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    { Name: &lt;span class="str"&gt;&amp;quot;MouthCannon&amp;quot;&lt;/span&gt;, Level: 99 }&lt;/pre&gt;

    &lt;pre&gt;                    ]&lt;/pre&gt;

    &lt;pre class="alt"&gt;                };&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;var&lt;/span&gt; json = JSON.stringify(obj);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                $(&lt;span class="str"&gt;&amp;quot;#txtJson&amp;quot;&lt;/span&gt;).val(json);&lt;/pre&gt;

    &lt;pre&gt;            }&lt;/pre&gt;

    &lt;pre class="alt"&gt;        });&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;form1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;textarea&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;txtJson&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;rows&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;6&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;cols&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;60&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;textarea&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:Button&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;btnGo&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Convert&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;onclick&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;btnGo_Click&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;textarea&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;txtClass&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;rows&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;18&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;cols&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;60&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;textarea&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;執行結果如下。在這個範例中，Javascript的Rank屬性是具有Code, Name屬性的物件，而Skills則是個物件陣列，陣列元素物件具有Name, Level兩個屬性。因此，在產生的.NET Class宣告中，除了主類別CRoot用來承接JSON轉換結果外，還要多宣告CRank跟CSkills兩個子類別。&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6496/original.aspx" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;好，看看程式怎麼寫:&lt;/p&gt;

&lt;div class="BlogCodeBlock"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Newtonsoft.Json;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Newtonsoft.Json.Linq;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; JSON2Class_Default : System.Web.UI.Page&lt;/pre&gt;

    &lt;pre&gt;{&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnGo_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        JObject jo =&lt;/pre&gt;

    &lt;pre&gt;            JsonConvert.DeserializeObject&amp;lt;JObject&amp;gt;(txtJson.Value);&lt;/pre&gt;

    &lt;pre class="alt"&gt;        JsonClassParser.RegisterClass(jo, &lt;span class="str"&gt;&amp;quot;Root&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;        txtClass.Value = JsonClassParser.GenClassCode();&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;}&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; JsonClassParser&lt;/pre&gt;

    &lt;pre class="alt"&gt;{&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; RawClass&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ClassName;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; PropertyHash;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Properties;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//蒐集所有類別&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; List&amp;lt;RawClass&amp;gt; Library&lt;/pre&gt;

    &lt;pre class="alt"&gt;        = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;RawClass&amp;gt;();&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; getCLSType(JTokenType t)&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;switch&lt;/span&gt; (t)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Boolean:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;bool&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Bytes:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;byte[]&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Date:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;DateTime&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Float:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;decimal&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Integer:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;int&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.String:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;string&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ApplicationException(&lt;/pre&gt;

    &lt;pre&gt;                    t.ToString() + &lt;span class="str"&gt;&amp;quot; is not supported&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//註冊類別&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; RegisterClass(JObject jo, &lt;span class="kwrd"&gt;string&lt;/span&gt; className) &lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        RawClass c = &lt;span class="kwrd"&gt;new&lt;/span&gt; RawClass();&lt;/pre&gt;

    &lt;pre&gt;        c.ClassName = &lt;span class="str"&gt;&amp;quot;C&amp;quot;&lt;/span&gt; + &lt;/pre&gt;

    &lt;pre class="alt"&gt;            className ??&lt;/pre&gt;

    &lt;pre&gt;            Path.GetFileNameWithoutExtension(&lt;/pre&gt;

    &lt;pre class="alt"&gt;            Path.GetTempFileName());&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="rem"&gt;//將所有類別組成Hash字串，用以比對類別是否相同&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        c.PropertyHash =&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt;.Join(&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre class="alt"&gt;            jo.Properties().Select(o =&amp;gt; o.Name).ToArray());&lt;/pre&gt;

    &lt;pre&gt;        c.Properties = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (JProperty p &lt;span class="kwrd"&gt;in&lt;/span&gt; jo.Properties())&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; t = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;switch&lt;/span&gt; (p.Value.Type)&lt;/pre&gt;

    &lt;pre class="alt"&gt;            {&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Object:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    t = RegisterClass((JObject)jo[p.Name], p.Name);&lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Array:&lt;/pre&gt;

    &lt;pre&gt;                    JArray ary = (JArray)jo[p.Name];&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;string&lt;/span&gt; typeName = &lt;span class="kwrd"&gt;null&lt;/span&gt;;                    &lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (JToken jv &lt;span class="kwrd"&gt;in&lt;/span&gt; ary)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    {&lt;/pre&gt;

    &lt;pre&gt;                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (jv.Type == JTokenType.Array)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ApplicationException(&lt;/pre&gt;

    &lt;pre&gt;                                &lt;span class="str"&gt;&amp;quot;Array of array is not supported!&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;string&lt;/span&gt; s =&lt;/pre&gt;

    &lt;pre&gt;                            jv.Type == JTokenType.Object ?&lt;/pre&gt;

    &lt;pre class="alt"&gt;                            RegisterClass((JObject)jv, p.Name) :&lt;/pre&gt;

    &lt;pre&gt;                            getCLSType(jv.Type);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (typeName == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;                            typeName = s;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (typeName != s)&lt;/pre&gt;

    &lt;pre&gt;                            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ApplicationException(&lt;/pre&gt;

    &lt;pre class="alt"&gt;                                &lt;span class="str"&gt;&amp;quot;Complex array is not supported!&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;                    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    t = typeName + &lt;span class="str"&gt;&amp;quot;[]&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Boolean:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Date:&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Float:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.Integer:&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;case&lt;/span&gt; JTokenType.String:&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    t = getCLSType(p.Value.Type);&lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ApplicationException(&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    p.Type.ToString() + &lt;span class="str"&gt;&amp;quot; is not supported!&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;            }&lt;/pre&gt;

    &lt;pre class="alt"&gt;            c.Properties.Add(p.Name, t);&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//檢查是否已有重覆類別存在&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        var q = (from o &lt;span class="kwrd"&gt;in&lt;/span&gt; Library&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;where&lt;/span&gt; o.PropertyHash == c.PropertyHash&lt;/pre&gt;

    &lt;pre&gt;                select o).SingleOrDefault();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//不存在時新增&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (q == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            Library.Add(c);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; c.ClassName;&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="rem"&gt;//存在時傳回既有類別&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; q.ClassName;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GenClassCode()&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        StringBuilder sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (RawClass rc &lt;span class="kwrd"&gt;in&lt;/span&gt; Library)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            sb.AppendFormat(&lt;span class="str"&gt;&amp;quot;public class {0} {{\r\n&amp;quot;&lt;/span&gt;, rc.ClassName);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; p &lt;span class="kwrd"&gt;in&lt;/span&gt; rc.Properties.Keys)&lt;/pre&gt;

    &lt;pre&gt;            {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                sb.AppendFormat(&lt;span class="str"&gt;&amp;quot;  public {0} {1} {{ get; set; }}\r\n&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;                    rc.Properties[p], p);&lt;/pre&gt;

    &lt;pre class="alt"&gt;            }&lt;/pre&gt;

    &lt;pre&gt;            sb.AppendLine(&lt;span class="str"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; sb.ToString();&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;雖然演算邏輯有點小複雜，但還是能在150列內將程式寫完，C#真是個好語言呀!! &lt;/p&gt;

&lt;p&gt;程式先藉用JSON.NET的JObject動態物件模型逐一找出屬性，分析其型別，當型別為物件時，則用遞迴技巧再針對物件分析生出對應的子類別。當型別為陣列時，則分析陣列元素型別，決定宣告成何種陣列? 不過為避免過度複雜，我設了限制--陣列所有元素必須為同一型別! 當然，陣列元素型別也可以是物件，一樣用遞迴方式產生對應.NET子類別，但一樣受陣列元素單一型別的限制。另外，同型別物件可能被分析多次，我透過比對所有屬性名稱判斷類別是否為同一個。&lt;/p&gt;

&lt;p&gt;程式未經大量測試，但初步試玩OK。有興趣的人可以拿回去玩玩，發現有Bug請再告知。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6497" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>CODE-使用JSON.NET處理動態物件屬性</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/06/05/json-net-jobject-example.aspx</link><pubDate>Fri, 04 Jun 2010 20:48:38 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6491</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=6491</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/06/05/json-net-jobject-example.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;之前在文章裡&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/04/21/asp-net-json.aspx"&gt;提過&lt;/a&gt;.NET內建兩種JSON轉換工具: JavaScriptSerializer及DataContractJsonSerializer。不過，它們都基於一個假設--&amp;quot;JSON轉換對象是事先已知的Class&amp;quot;!&lt;/p&gt; &lt;p&gt;在某些狀況下，前端所傳回的JSON字串是開發階段無法完全掌握的。&lt;/p&gt; &lt;p&gt;舉個極端的例子。在Javascript裡可用以下寫法搞出一個你做夢都想不到的物件，轉成JSON傳到後端:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#00ff00"&gt;var o = {}; &lt;br /&gt;for (var i = 0; i &amp;lt; 10; i++) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; o[&amp;quot;Prop&amp;quot; + Math.floor(Math.random() * 100000)] = i; &lt;br /&gt;var jsonString = JSON.stringify(o);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;遇到這種機車需求，難道Server端就束手無策了嗎?&lt;/p&gt; &lt;p&gt;Thanks God, We have &lt;a href="http://json.codeplex.com/"&gt;JSON.NET&lt;/a&gt;!! 一個極為出色的Open Source JSON解決方案，提供了如同JavaScriptSerializer序列化及反序列化JSON字串的功能，甚至支援LINQ式操作，最重要的是它可透過JObject的物件模型支援&amp;quot;動態物件&amp;quot;，解決類別屬性不固定的問題。&lt;/p&gt; &lt;p&gt;以下是簡單的動態物件應用示範: (JSON.NET有親切易讀的&lt;a href="http://james.newtonking.com/projects/json/help/"&gt;說明文件&lt;/a&gt;，對Open Source Project來說十分難得，不可錯過了)&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Newtonsoft.Json;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Newtonsoft.Json.Linq;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DynamicJson : System.Web.UI.Page&lt;/pre&gt;&lt;pre class="alt"&gt;{&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Member&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime Birthday;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Level;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[] Records;&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//使用傳統的強型別直接轉換&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        Member jeffrey = &lt;span class="kwrd"&gt;new&lt;/span&gt; Member()&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            Name = &lt;span class="str"&gt;&amp;quot;Jeffrey&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;            Birthday = &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(1990, 1, 1),&lt;/pre&gt;&lt;pre class="alt"&gt;            Level = 99,&lt;/pre&gt;&lt;pre&gt;            Records = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[] { 1024, 9999, 32767 }&lt;/pre&gt;&lt;pre class="alt"&gt;        };&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//(哇塞! 我被序列化了)&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        Response.Write(&lt;/pre&gt;&lt;pre&gt;            JsonConvert.SerializeObject(jeffrey));&lt;/pre&gt;&lt;pre class="alt"&gt;        Response.Write(&lt;span class="str"&gt;&amp;quot;&amp;lt;hr /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;        &lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//動態產生Json的範例&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        JObject jo = &lt;span class="kwrd"&gt;new&lt;/span&gt; JObject();&lt;/pre&gt;&lt;pre class="alt"&gt;        jo.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; JProperty(&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Jeffrey&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre&gt;        jo.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; JProperty(&lt;span class="str"&gt;&amp;quot;Birthday&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(1990, 1, 1)));&lt;/pre&gt;&lt;pre class="alt"&gt;        jo.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; JProperty(&lt;span class="str"&gt;&amp;quot;Level&amp;quot;&lt;/span&gt;, 99));&lt;/pre&gt;&lt;pre&gt;        JArray ja = &lt;span class="kwrd"&gt;new&lt;/span&gt; JArray();&lt;/pre&gt;&lt;pre class="alt"&gt;        ja.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; JValue(1024));&lt;/pre&gt;&lt;pre&gt;        ja.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; JValue(9999));&lt;/pre&gt;&lt;pre class="alt"&gt;        ja.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; JValue(32767));&lt;/pre&gt;&lt;pre&gt;        jo.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; JProperty(&lt;span class="str"&gt;&amp;quot;Records&amp;quot;&lt;/span&gt;, ja));&lt;/pre&gt;&lt;pre class="alt"&gt;        Response.Write(JsonConvert.SerializeObject(jo));&lt;/pre&gt;&lt;pre&gt;        Response.Write(&lt;span class="str"&gt;&amp;quot;&amp;lt;hr /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//也可以像XDocument一樣一次宣告&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        jo = &lt;span class="kwrd"&gt;new&lt;/span&gt; JObject(&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; JProperty(&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Jeffrey&amp;quot;&lt;/span&gt;),&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; JProperty(&lt;span class="str"&gt;&amp;quot;Birthday&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(1990, 1, 1)),&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; JProperty(&lt;span class="str"&gt;&amp;quot;Level&amp;quot;&lt;/span&gt;, 99),&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;new&lt;/span&gt; JProperty(&lt;span class="str"&gt;&amp;quot;Records&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;new&lt;/span&gt; JArray(&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;new&lt;/span&gt; JValue(1024), &lt;span class="kwrd"&gt;new&lt;/span&gt; JValue(9999),&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;new&lt;/span&gt; JValue(32767)&lt;/pre&gt;&lt;pre class="alt"&gt;                    )&lt;/pre&gt;&lt;pre&gt;                )&lt;/pre&gt;&lt;pre class="alt"&gt;            );&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; jsonString = JsonConvert.SerializeObject(jo);&lt;/pre&gt;&lt;pre class="alt"&gt;        Response.Write(jsonString);&lt;/pre&gt;&lt;pre&gt;        Response.Write(&lt;span class="str"&gt;&amp;quot;&amp;lt;hr /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;/* &lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt; jsonString內容為&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;{&amp;quot;Name&amp;quot;:&amp;quot;Jeffrey&amp;quot;,&amp;quot;Birthday&amp;quot;:&amp;quot;\/Date(631123200000+0800)\/&amp;quot;,&amp;quot;Level&amp;quot;:99,&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt; &amp;quot;Records&amp;quot;:[1024,9999,32767]} &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt; */&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//JSON字串也可還原回JObject，動態存取&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        JObject restoredObject = JsonConvert.DeserializeObject&amp;lt;JObject&amp;gt;(&lt;/pre&gt;&lt;pre&gt;            jsonString);&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//JObject可使用LINQ方式存取&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        var q = from p &lt;span class="kwrd"&gt;in&lt;/span&gt; restoredObject.Properties()&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;where&lt;/span&gt; p.Name == &lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                select p;&lt;/pre&gt;&lt;pre class="alt"&gt;        Response.Write(&lt;span class="str"&gt;&amp;quot;&amp;lt;li&amp;gt;Name = &amp;quot;&lt;/span&gt; + (&lt;span class="kwrd"&gt;string&lt;/span&gt;)q.First().Value);&lt;/pre&gt;&lt;pre&gt;        Response.Write(&lt;span class="str"&gt;&amp;quot;&amp;lt;li&amp;gt;Birthday = &amp;quot;&lt;/span&gt; +&lt;/pre&gt;&lt;pre class="alt"&gt;            (DateTime)jo.Property(&lt;span class="str"&gt;&amp;quot;Birthday&amp;quot;&lt;/span&gt;).Value);&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;int&lt;/span&gt;[] records =&lt;/pre&gt;&lt;pre class="alt"&gt;            ((JArray)jo.Property(&lt;span class="str"&gt;&amp;quot;Records&amp;quot;&lt;/span&gt;).Value)&lt;/pre&gt;&lt;pre&gt;            .Select(o =&amp;gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt;)o).ToArray();&lt;/pre&gt;&lt;pre class="alt"&gt;        Response.Write(&lt;span class="str"&gt;&amp;quot;&amp;lt;li&amp;gt;Records = &amp;quot;&lt;/span&gt; + &lt;span class="kwrd"&gt;string&lt;/span&gt;.Join(&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;, &lt;/pre&gt;&lt;pre&gt;            records.Select(o =&amp;gt; o.ToString()).ToArray()));&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;/*&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;         * == 得到結果 ==&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;         * Name = Jeffrey&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;         * Birthday = 1/1/1990 12:00:00 AM&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;         * Records = 1024,9999,32767&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;         */&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;        Response.End();&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6491" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>CODE-ASPX接收jQuery.ajax傳送XML文件範例</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/10/02/jquery-ajax-xml-and-aspx.aspx</link><pubDate>Fri, 02 Oct 2009 03:07:42 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:5405</guid><dc:creator>Jeffrey</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=5405</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/10/02/jquery-ajax-xml-and-aspx.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;今天應用到以jQuery.ajax送出XML文件，以ASPX接收處理的寫法。在倉庫挖了好久，才找出不久前剛寫過的程式碼參考。為了避免中年記憶衰退成為我活到老，Coding到老路上的絆腳石，整理一下程式貼成KB，也順便與有此需求的鄉親們分享。&lt;/p&gt; &lt;p&gt;HttpRequest要傳遞整份XML文件時，並不是將XML字串放在參數中，而是把整個XML內容當成POST Request的主體，因此在jQuery端與ASPX端跟一般呼叫寫法有些不同。&lt;/p&gt; &lt;p&gt;傳送時，必須直接使用jQuery.ajax()以精確調控參數，沒法用$.post()偷懶。參數中conteType: &amp;quot;text/xml&amp;quot;用來向Web Server表明內容物為XML，processData: false則是要求jQuery將data內容原汁原味上傳，不要做任何解析或修改。&lt;/p&gt; &lt;p&gt;而在ASPX端，不是用Request[&amp;quot;..&amp;quot;]接參數，而是要用Request.InputStream接入上傳內容。我在程式串同時列出2.0 XmlDocument及3.5 XDocument的做法比較，3.5明顯簡潔許多。&lt;/p&gt; &lt;p&gt;程式碼如下，有興趣的人就拿回去玩吧!&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="asp"&gt;&amp;lt;%@ Import Namespace=&amp;quot;System.Xml&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Import Namespace=&amp;quot;System.Xml.Linq&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="asp"&gt;&amp;lt;%@ Import Namespace=&amp;quot;System.IO&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="html"&gt;DOCTYPE&lt;/span&gt; &lt;span class="attr"&gt;html&lt;/span&gt; &lt;span class="attr"&gt;PUBLIC&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (Request[&lt;span class="str"&gt;&amp;quot;mode&amp;quot;&lt;/span&gt;] == &lt;span class="str"&gt;&amp;quot;send&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="rem"&gt;//LINQ way&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                XDocument xd =&lt;/pre&gt;&lt;pre class="alt"&gt;                    XDocument.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; StreamReader(Request.InputStream));&lt;/pre&gt;&lt;pre&gt;                xd.Root.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;&amp;quot;Mark&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Inserted by ASP.NET 3.5&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;                Response.Write(xd.ToString());&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="rem"&gt;/* Traditional Way&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;                XmlDocument xd2 = new XmlDocument();&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;                xd2.Load(Request.InputStream);&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;                XmlElement xe = xd2.CreateElement(&amp;quot;Mark&amp;quot;);&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;                xe.InnerText = &amp;quot;Inserted by ASP.NET 2.0&amp;quot;;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;                xd2.DocumentElement.AppendChild(xe);&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;                Response.Write(xd2.OuterXml);&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;                */&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                Response.ContentType = &lt;span class="str"&gt;&amp;quot;text/xml&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="rem"&gt;//return text, raise $.ajax error event&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                Response.ContentType = &lt;span class="str"&gt;&amp;quot;text/plain&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;                Response.Write(ex.Message);&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            Response.End();&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&amp;lt;html xmlns=&lt;span class="str"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;lt;head runat=&lt;span class="str"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;title&amp;gt;jQuery Post XML Sample&amp;lt;/title&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;script src=&lt;span class="str"&gt;&amp;quot;js/jquery-1.3.2.js&amp;quot;&lt;/span&gt; type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;function&lt;/span&gt; postXml(url, xmlSrc, callback) {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; xmlString = &lt;/pre&gt;&lt;pre class="alt"&gt;                jQuery.isXMLDoc(xmlSrc) ?&lt;/pre&gt;&lt;pre&gt;                xmlSrc.xml || (&lt;span class="kwrd"&gt;new&lt;/span&gt; XMLSerializer()).serializeToString(xmlSrc) :&lt;/pre&gt;&lt;pre class="alt"&gt;                xmlSrc;&lt;/pre&gt;&lt;pre&gt;            $.ajax({&lt;/pre&gt;&lt;pre class="alt"&gt;                url: url,&lt;/pre&gt;&lt;pre&gt;                contentType: &lt;span class="str"&gt;&amp;quot;text/xml&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                data: xmlString,&lt;/pre&gt;&lt;pre&gt;                dataType: &lt;span class="str"&gt;&amp;quot;xml&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                success: &lt;span class="kwrd"&gt;function&lt;/span&gt;(x) { callback(x); },&lt;/pre&gt;&lt;pre&gt;                error: &lt;span class="kwrd"&gt;function&lt;/span&gt;(xhr, textStatus, thrownError) { &lt;/pre&gt;&lt;pre class="alt"&gt;                        alert(&lt;span class="str"&gt;&amp;quot;Error:&amp;quot;&lt;/span&gt; + xhr.responseText);  },&lt;/pre&gt;&lt;pre&gt;                processData: &lt;span class="kwrd"&gt;false&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                type: &lt;span class="str"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            });&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;        $(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre class="alt"&gt;            $(&lt;span class="str"&gt;&amp;quot;#btnSend&amp;quot;&lt;/span&gt;).click(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;                postXml(&lt;span class="str"&gt;&amp;quot;AjaxPostXmlSample.aspx?mode=send&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                $(&lt;span class="str"&gt;&amp;quot;#taXml&amp;quot;&lt;/span&gt;).val(), &lt;span class="kwrd"&gt;function&lt;/span&gt;(xd) {&lt;/pre&gt;&lt;pre&gt;                    alert(xd.xml || &lt;/pre&gt;&lt;pre class="alt"&gt;                    (&lt;span class="kwrd"&gt;new&lt;/span&gt; XMLSerializer()).serializeToString(xd));&lt;/pre&gt;&lt;pre&gt;                });&lt;/pre&gt;&lt;pre class="alt"&gt;            });&lt;/pre&gt;&lt;pre&gt;        });&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;textarea&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;taXml&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;cols&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;40&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;rows&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;5&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;span class="attr"&gt;&amp;amp;lt;&lt;/span&gt;Books&lt;span class="attr"&gt;&amp;amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;   &lt;span class="attr"&gt;&amp;amp;lt;&lt;/span&gt;Book Title=&amp;quot;The Art of Trouble-Shooting&amp;quot; Author=&amp;quot;Darkthread&amp;quot; /&lt;span class="attr"&gt;&amp;amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="attr"&gt;&amp;amp;lt;&lt;/span&gt;/Books&lt;span class="attr"&gt;&amp;amp;gt;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;textarea&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;button&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;btnSend&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Send&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=5405" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>輕量級的js檔打包解決方案</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/09/18/js-packing.aspx</link><pubDate>Thu, 17 Sep 2009 20:51:23 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:5334</guid><dc:creator>Jeffrey</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=5334</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/09/18/js-packing.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;最近在嘗試將一個功能強大的jQuery Plugin【&lt;a href="http://www.trirand.com/blog/"&gt;jqGrid&lt;/a&gt;】整到專案裡，它的功能與彈性讓人印象深刻(不過要上手得花點時間摸索)，大家可以直接看&lt;a href="http://trirand.com/jqgrid/jqgrid.html"&gt;線上展示&lt;/a&gt;，應該就能感受其威力。&lt;/p&gt; &lt;p&gt;jqGrid有個貼心的設計--將功能模組化。各模組的程式分散在多個js檔，有用到才需要載入，避免Client端載入肥大js只使用其中一丁點功能，白白浪費載入時間及頻寬。(剛好前些時候James Padolsey也提到&lt;a href="http://james.padolsey.com/javascript/jquery-plugins-are-broken/"&gt;這點&lt;/a&gt;，甚至覺得殺雞不必用牛刀，小功能或許自己寫會更有效率兼便練功)&lt;/p&gt; &lt;p&gt;jqGrid提供了兩種做法: &lt;a href="http://www.trirand.com/blog/?page_id=6"&gt;線上挑選模組&lt;/a&gt;後打包成單一js檔，或透過jquery.jqGrid.js動態載入。在開發階段我選擇了動態載入法，卻發現疑似因載入時間差的關係，Reload多次時，偶爾會出現js來不及載入而出錯，於是決定改回靜態include。結果在HTML檔出現很壯觀的景象:&lt;/p&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/5331/500x375.aspx" alt="" /&gt; &lt;/p&gt; &lt;p&gt;當然，這是極度誇張的特例，但依過去的經驗裡，網頁用的plugin種類一多，先後include十來個js檔也是很平常的。這表示使用者開啟網頁的同時，還一併丟出十來個Request，每個Request都有傳輸與處理的Overhead，平白增加伺服器負擔。同時，用Copy And Paste的方式在每個網頁裡維護又臭又長的include清單，顯然也有違程式簡潔性並且不易修改。&lt;/p&gt; &lt;p&gt;於是，我想要改善這個問題。發噗提出想法後，不少噗友提供了很好的意見。市場上有些現成的解決方案，例如: &lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;YUI&lt;/a&gt;可以壓縮合併JS/CSS、Microsoft實驗室則有&lt;a href="http://www.dotblogs.com.tw/jimmyyu/archive/2009/09/11/10563.aspx"&gt;DOLOTO&lt;/a&gt;、另外還有些朋友習慣用MasterPage解決這個問題。&lt;/p&gt; &lt;p&gt;考量了一下，我理想中的合併下載工具應該透過單一ASPX網頁就能解決，在運用上會比引用MasterPage來得靈活一點(提供輔助工具會比改變網頁架構容易些，而且不侷限於ASPX，HTM、JS裡也可以引用)，也有較大的組合彈性；至於DOLOTO，看起來很強大，但引用過程較繁瑣，且不確定jQuery裡的函數/Plugin被分割肢解+動態載入會不會出問題；至於YUI，好像比較傾向靜態合併，而且ASP.NET + jQuery外再多扯進來另一個Framework有點像在找其他同事麻煩，尤其是我只是想喝杯牛奶罷了。&lt;/p&gt; &lt;p&gt;評估程式邏輯並不複雜，決定立刻捲起袖子動手做，最壞只是損失一些工時。沒一會兒，JsLoader.aspx誕生了:&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&amp;lt;%@ Page Language=&lt;span class="str"&gt;&amp;quot;C#&amp;quot;&lt;/span&gt; %&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;%@ Import Namespace=&lt;span class="str"&gt;&amp;quot;System.IO&amp;quot;&lt;/span&gt; %&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;lt;%@ Import Namespace=&lt;span class="str"&gt;&amp;quot;System.Collections.Generic&amp;quot;&lt;/span&gt; %&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;script runat=&lt;span class="str"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; jsQueue = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; jsPool = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; JS_SET_PREFIX = &lt;span class="str"&gt;&amp;quot;JSS_&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt;[] f = (Request[&lt;span class="str"&gt;&amp;quot;f&amp;quot;&lt;/span&gt;] ?? &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;            .Split(&lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;char&lt;/span&gt;[] {&lt;span class="str"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;,&lt;span class="str"&gt;&amp;#39;;&amp;#39;&lt;/span&gt;}, StringSplitOptions.RemoveEmptyEntries);&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; jsFile &lt;span class="kwrd"&gt;in&lt;/span&gt; f)&lt;/pre&gt;&lt;pre class="alt"&gt;            queueJs(jsFile);            &lt;/pre&gt;&lt;pre&gt;        Response.ContentType = &lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; js &lt;span class="kwrd"&gt;in&lt;/span&gt; jsQueue)&lt;/pre&gt;&lt;pre&gt;            Response.Write(jsPool[js]);&lt;/pre&gt;&lt;pre class="alt"&gt;        Response.End();&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; queueJs(&lt;span class="kwrd"&gt;string&lt;/span&gt; jsFile) &lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt;[] p = jsFile.Split(&lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;char&lt;/span&gt;[] {&lt;span class="str"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;,&lt;span class="str"&gt;&amp;#39;;&amp;#39;&lt;/span&gt;}, &lt;/pre&gt;&lt;pre&gt;            StringSplitOptions.RemoveEmptyEntries);&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//if multi-part&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (p.Length &amp;gt; 1)&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; f &lt;span class="kwrd"&gt;in&lt;/span&gt; p)&lt;/pre&gt;&lt;pre class="alt"&gt;                queueJs(f);&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//lower case&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        jsFile = jsFile.ToLower();&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//js set name without .js&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (jsFile.EndsWith(&lt;span class="str"&gt;&amp;quot;.js&amp;quot;&lt;/span&gt;))&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//if already queued&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (jsPool.ContainsKey(jsFile)) &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//else put the js into queue&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            jsQueue.Add(jsFile);&lt;/pre&gt;&lt;pre class="alt"&gt;            jsPool.Add(jsFile, getJsContent(jsFile));&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="rem"&gt;//if set, try to find it from web.config&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; jsFiles =&lt;/pre&gt;&lt;pre&gt;                System.Configuration.ConfigurationManager.AppSettings[&lt;/pre&gt;&lt;pre class="alt"&gt;                    JS_SET_PREFIX + jsFile];&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(jsFiles))&lt;/pre&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;pre&gt;                jsQueue.Add(jsFile);&lt;/pre&gt;&lt;pre class="alt"&gt;                jsPool.Add(jsFile,&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;alert(&amp;#39;JsLoader Error: [{0}] set not configured!&amp;#39;);&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                    EscapeStringForJS(jsFile)));&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="rem"&gt;//process the predefined file list &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                queueJs(jsFiles); &lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//Get js file content&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; getJsContent(&lt;span class="kwrd"&gt;string&lt;/span&gt; jsFile)&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; file = Server.MapPath(&lt;span class="str"&gt;&amp;quot;./&amp;quot;&lt;/span&gt; + jsFile);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!File.Exists(file))&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;alert(&amp;#39;JsLoader Error: [{0}] not found!&amp;#39;);&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                    EscapeStringForJS(jsFile));&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="rem"&gt;//Add cache/packing module here if you want&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; File.ReadAllText(file);&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;catch&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ApplicationException(&lt;span class="str"&gt;&amp;quot;Failed to process &amp;quot;&lt;/span&gt; + jsFile);&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;/// Replace characters for Javscript string literals&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name=&amp;quot;text&amp;quot;&amp;gt;raw string&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;escaped string&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; EscapeStringForJS(&lt;span class="kwrd"&gt;string&lt;/span&gt; s)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; s.Replace(&lt;span class="str"&gt;@&amp;quot;\&amp;quot;, @&amp;quot;&lt;/span&gt;\\&lt;span class="str"&gt;&amp;quot;)&lt;/pre&gt;&lt;pre&gt;                .Replace(&amp;quot;&lt;/span&gt;\b&lt;span class="str"&gt;&amp;quot;, @&amp;quot;&lt;/span&gt;\b&lt;span class="str"&gt;&amp;quot;)&lt;/pre&gt;&lt;pre class="alt"&gt;                .Replace(&amp;quot;&lt;/span&gt;\f&lt;span class="str"&gt;&amp;quot;, @&amp;quot;&lt;/span&gt;\f&lt;span class="str"&gt;&amp;quot;)&lt;/pre&gt;&lt;pre&gt;                .Replace(&amp;quot;&lt;/span&gt;\n&lt;span class="str"&gt;&amp;quot;, @&amp;quot;&lt;/span&gt;\n&lt;span class="str"&gt;&amp;quot;)&lt;/pre&gt;&lt;pre class="alt"&gt;                .Replace(&amp;quot;&lt;/span&gt;\0&lt;span class="str"&gt;&amp;quot;, @&amp;quot;&lt;/span&gt;\0&lt;span class="str"&gt;&amp;quot;)&lt;/pre&gt;&lt;pre&gt;                .Replace(&amp;quot;&lt;/span&gt;\r&lt;span class="str"&gt;&amp;quot;, @&amp;quot;&lt;/span&gt;\r&lt;span class="str"&gt;&amp;quot;)&lt;/pre&gt;&lt;pre class="alt"&gt;                .Replace(&amp;quot;&lt;/span&gt;\t&lt;span class="str"&gt;&amp;quot;, @&amp;quot;&lt;/span&gt;\t&lt;span class="str"&gt;&amp;quot;)&lt;/pre&gt;&lt;pre&gt;                .Replace(&amp;quot;&lt;/span&gt;\v&lt;span class="str"&gt;&amp;quot;, @&amp;quot;&lt;/span&gt;\v&lt;span class="str"&gt;&amp;quot;)&lt;/pre&gt;&lt;pre class="alt"&gt;                .Replace(&amp;quot;&lt;/span&gt;&amp;#39;&lt;span class="str"&gt;&amp;quot;, @&amp;quot;&lt;/span&gt;\&amp;#39;&lt;span class="str"&gt;&amp;quot;)&lt;/pre&gt;&lt;pre&gt;                .Replace(@&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;, @&amp;quot;&lt;/span&gt;\&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&amp;quot;);&lt;/pre&gt;&lt;pre class="alt"&gt;    }    &lt;/pre&gt;&lt;pre&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;JsLoader.aspx的工作原理很簡單，程式放在js同層目錄下，網頁裡寫成&amp;lt;script type=&amp;quot;text/javascxript&amp;quot; src=&amp;quot;/js/JsLoader.aspx?f=js1.js,js2.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;就可以動態將js1.js與js2.js兩個檔案合併成一個傳回。而在getJsContent()裡，還可以加入Cache及壓縮js的機制(例如: 加參數就改成載入壓縮過的.min.js版本)，讓效率更好一些。不過，我加入最重要的簡化是除了直接列出js檔名外，可在/js/web.config裡定義一些預設的&amp;quot;套件&amp;quot;，這樣子就可以用JsLoader.aspx?f=jqgrid取代原本一長串js檔案清單，而多組&amp;quot;套件&amp;quot;也可以再組成一個&amp;quot;套餐&amp;quot;(如JSS_gridpage)，如某幾個網頁有共同的js載入需求，可以只宣告一次，用在多個網頁上。檔案清單、套件、套餐三種方式可以視需要自由組合運用。&lt;/p&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;&amp;lt;!-- Use JSS_[JS Set Name], JS Set Name should be lower case --&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;JSS_jqgrid&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre&gt;&lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;jquery-ui-1.7.1.custom.min.js,i18n/grid.locale-tw.js,...略...,jqModal.js,jqDnR.js&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;JSS_nummask&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;jquery.afaNumMask.js&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;JSS_dyndatetime&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;jquery.dynDateTime.js,../css/calendar/calendar-tw.js&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;JSS_json2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;json2.js&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;JSS_gridpage&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;jqgrid,json2,nummask,dyndatetime&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;最後還是要講一下JsLoader.aspx的黑暗面，將多個js檔包在一起的做法，固然可減少Request次數，但js檔過於肥大，會讓載入時間變久，而Debug時js檔太大，Debugger處理起來效率不佳。過與不及都不是好事，尺度怎麼拿捏，大家見機行事吧!&lt;/p&gt;
&lt;p&gt;PS: 順道推一下&lt;a href="http://www.dotblogs.com.tw/topcat/Default.aspx"&gt;小喵&lt;/a&gt;介紹的&lt;a href="http://www.dotblogs.com.tw/topcat/archive/2009/09/16/10658.aspx"&gt;dynDateTime Plugin&lt;/a&gt;，我從ASP時代就一直仰賴它的&lt;a href="http://www.dynarch.com/projects/calendar/"&gt;前身&lt;/a&gt;解決日期選擇問題，如今有了jQuery Plugin版本，自然要力挺到底了!!&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=5334" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>【雛型】Docx套版列印功能試作</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/07/30/docx-templating.aspx</link><pubDate>Wed, 29 Jul 2009 11:57:09 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:5061</guid><dc:creator>Jeffrey</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=5061</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/07/30/docx-templating.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;在我的程式開發生涯中，套版輸出指定格式的報表/表單一直是揮之不去的煩人差事，沒什麼營養，偏偏在每個案子裡幾乎都像小強一樣冒出來。&lt;/p&gt;  &lt;p&gt;面對這類需求，轉成網頁是下策，因為列印時排版格式常會亂到一塌糊塗，鮮少讓人滿意。在經驗裡，Reporting Service是不錯的選擇(而且免費)。&lt;/p&gt;  &lt;p&gt;但有些報表如確認書、通知書，在格式上並非Gird格式，跟Reporting Service最擅長的表格呈現有點差距，數量一多，要將User提供的Word檔一一轉成Reporting Service報表便成了苦差事，尤其某些文件被要求必須模仿到跟原始樣版分毫不差，常為了一兩公釐急死大丈夫。(有時，所謂原有樣版不過是某個User信手捻來的作品，並非官頒公訂，也沒人說過排版必須完全相符，但是你也知道的，各地風俗民情不同，尤其是澳洲...)&lt;/p&gt;  &lt;p&gt;當以上情境發生，直接把User提供Word樣版裡文字換一換，照樣生出個Word檔來，在我看來是最簡便直覺省工的解法。&lt;/p&gt;  &lt;p&gt;依我所知，動態產生Word要在ASP.NET上實現，有幾種解法，個人評估分析如下:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;font color="#ff8000"&gt;利用Office Automation&lt;/font&gt;(就如同VBA操作Word/Excel Object Model的做法)       &lt;br /&gt;在Server端(ASP.NET)使用Office Automation技巧有些額外的風險，我自己有過不好的經驗，依&lt;a href="http://support.microsoft.com/kb/257757"&gt;MS KB&lt;/a&gt;的說法也不建議。 &lt;/li&gt;    &lt;li&gt;&lt;font color="#ff8000"&gt;產出HTML後標註ContentType，讓Word/Excel開啟&lt;/font&gt;       &lt;br /&gt;先前曾&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/17/1143.aspx"&gt;貼文介紹過&lt;/a&gt;這種做法，但逼真度與真實doc/xls有段差距，例如: doc沒法精確分頁、xls不支援多Worksheet... 等等。 &lt;/li&gt;    &lt;li&gt;&lt;font color="#ff8000"&gt;使用3rd Party元件直接產生Office文件&lt;/font&gt;       &lt;br /&gt;剛才提到的&lt;a href="http://support.microsoft.com/kb/257757"&gt;MS KB&lt;/a&gt;裡就有些建議的元件廠商，另外還有一家元件廠商&lt;a href="http://www.aspose.com/categories/file-format-components/aspose.words-for-.net-and-java/default.aspx"&gt;ASPOSE&lt;/a&gt;的名字也常被提到。只是，元件的價格通常不便宜。 &lt;/li&gt;    &lt;li&gt;&lt;font color="#ff8000"&gt;docx/xlsx OpenXML&lt;/font&gt;       &lt;br /&gt;Office 2007在檔案格式上做了大改革，揚離了過去的獨有二進位格式，變成公開的標準，而docx/xlsx，其實是ZIP起來的一堆XML及資源檔。這麼一來，修改XML也比以前搞封閉的二進位檔案格式簡單多了，也因為標準公開，可用的技術資源也多。      &lt;br /&gt;使用docx/xlsx固然便捷，缺點是產出的docx/xlsx Office 2003/2000無法直接開啟，所幸微軟提供了&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=zh-tw&amp;amp;FamilyID=3657ce88-7cfa-457a-9aec-f4f827f20cac"&gt;免費的Word Viewer&lt;/a&gt;可以用來檢視，另外也有&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=941b3470-3ae9-4aee-8f43-c6bb74cd1466&amp;amp;displaylang=zh-tw"&gt;Microsoft Office Word、Excel 及 PowerPoint 2007 檔案格式相容性套件&lt;/a&gt;能將docx/xlsx轉存為doc/xls。在我看來，這點是可被容忍的缺陷。因此，我決定設法試做OpenXML的解決方案。 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;雖然我們可以自行將docx Rename成.zip，解壓縮後取出XML修改再存回壓縮回去，但MS提供了更好的支援服務: (SDK文件裡的範例寫得簡單明瞭，讓我一下子就上手!! 哦哦~~ Open XML Format SDK，我要輕輕為你唱首歌)&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=AD0B72FB-4A1D-4C52-BDB5-7DD7E816D046&amp;amp;displaylang=en"&gt;Open XML Format SDK 1.0&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&amp;amp;DisplayLang=en"&gt;Open XML Format SDK 2.0&lt;/a&gt; (雖然在物件模型上更為結構化，呼叫起來更方便，但仍在Community Techinal Preview階段) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;因為我想做的套版只是更換特定字串，用1.0的寫法也不算太鳥，加上打算用來Production環境，不想承擔CTP的風險。所以我決定現階段先用1.0 SDK正式版來實作，日後有更複雜運用時再改版。&lt;/p&gt;  &lt;p&gt;今天只花了幾個小時，還真的把雛型做出來了:&lt;/p&gt;  &lt;p&gt;1.先用Word 2007存一個docx檔案，把其中要動態更換的文字用[$keyName$]的格式標起來。(這種[$...$]的格我還為它取了個名字--Parser Tag，從ASP時代，我就一直用它來玩範本套表的把戲)&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/5059/500x375.aspx" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;2.寫一小段程式，把[$keyName$]要更換的文字轉成Dictionary&amp;lt;string, string&amp;gt;，連同範本的檔案路徑一起傳給套表輔助元件DocxHelper，傳回的byte[]就是套表好的docx檔案內容。&lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnExport_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; template = Server.MapPath(&lt;span class="str"&gt;&amp;quot;Notice.docx&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; dct = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;()&lt;/pre&gt;

    &lt;pre&gt;            { { &lt;span class="str"&gt;&amp;quot;today&amp;quot;&lt;/span&gt;, DateTime.Today.ToString(&lt;span class="str"&gt;&amp;quot;yyyy-MM-dd&amp;quot;&lt;/span&gt;) },&lt;/pre&gt;

    &lt;pre class="alt"&gt;              { &lt;span class="str"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;, txtName.Text },&lt;/pre&gt;

    &lt;pre&gt;              { &lt;span class="str"&gt;&amp;quot;addr&amp;quot;&lt;/span&gt;, txtAddr.Text },&lt;/pre&gt;

    &lt;pre class="alt"&gt;              { &lt;span class="str"&gt;&amp;quot;amount&amp;quot;&lt;/span&gt;, txtAmount.Text } };&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        Response.Clear();&lt;/pre&gt;

    &lt;pre&gt;        Response.ContentType = &lt;span class="str"&gt;&amp;quot;application/octet-stream&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        Response.AddHeader(&lt;span class="str"&gt;&amp;quot;content-disposition&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;attachment;filename=Notice.docx&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;        Response.BinaryWrite(&lt;/pre&gt;

    &lt;pre class="alt"&gt;            Darkthread.OpenXml.DocxHelper.MakeDocx(&lt;/pre&gt;

    &lt;pre&gt;                Server.MapPath(&lt;span class="str"&gt;&amp;quot;Notice.docx&amp;quot;&lt;/span&gt;), &lt;/pre&gt;

    &lt;pre class="alt"&gt;                dct)&lt;/pre&gt;

    &lt;pre&gt;        );&lt;/pre&gt;

    &lt;pre class="alt"&gt;        Response.End();&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;3.實際跑起來，按下【匯出DOCX】，TextBox裡的文字就會被填進下載的docx中，很棒吧!! &lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/5060/500x375.aspx" alt="" /&gt; &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;&lt;strong&gt;&lt;font color="#00ff00"&gt;天哪，我真的中了大樂透了嗎? 不會吧? 莫非有人在耍我? (謎之聲: 不就是你自己嗎? 找時間去看一下精神科好唄?)&lt;/font&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;我打算在手邊的小案子試行這個新元件，陸續蒐集一些問題跟情境，待元件較為成熟後，到時再推出懶人包跟大家分享。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=5061" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>GridView的標題欄、列凍結效果(跨瀏覽器版)</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/18/supertable-plugin-for-jquery.aspx</link><pubDate>Tue, 17 Feb 2009 14:10:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:4240</guid><dc:creator>Jeffrey</dc:creator><slash:comments>54</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=4240</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/18/supertable-plugin-for-jquery.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;
&lt;p&gt;稍早發表了&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/17/gridview-fixed-header.aspx"&gt;GridView的標題列凍結效果&lt;/a&gt;，足以滿足工作上的需求，不過存在兩個缺點: 只支援FF及IE6/7、只能凍結列不能凍結欄(行)...&lt;/p&gt;
&lt;p&gt;不甘心事情只做一半，又挖了一下，驚喜地發現另一個版本: &lt;a href="http://www.matts411.com/post/super_tables/"&gt;Super Tables&lt;/a&gt;，可以支援Firefox 2+, Internet Explorer 5.5+, Safari 3+, Opera 9+ 以及Chrome，而且也支援直欄的凍結效果，在功能上大勝ScrollableTable，二話不說，通通包起來。&lt;/p&gt;
&lt;p&gt;SuperTable的原理與ScrollableTable不同，它需要額外的CSS以及在Table外包一層&amp;lt;div&amp;gt;，可視範圍大小由&amp;lt;div&amp;gt; Style決定，設定時參數也較多(如:fixedCols, headerRows...)，所以我寫了一個jQuery Plugin(jquery.superTable.js)把它包起來。有了Plugin的加持，只要一個toSuperTable(options)就可立即升級成有凍結效果的GridView了。&lt;/p&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;/////////////////////////////////////////////////////////////////////////////////////////&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;// Super Tables Plugin for jQuery - MIT Style License&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;// Copyright (c) 2009 Jeffrey Lee --- blog.darkthread.net&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;// A wrapper for Matt Murphy&amp;#39;s Super Tables http://www.matts411.com/post/super_tables/&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;// Contributors:&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;/////////////////////////////////////////////////////////////////////////////////////////&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;////// TO CALL: &lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;// $(&amp;quot;...&amp;quot;).toSuperTable(options)&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;////// OPTIONS: (order does not matter )&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;// cssSkin : string ( eg. &amp;quot;sDefault&amp;quot;, &amp;quot;sSky&amp;quot;, &amp;quot;sOrange&amp;quot;, &amp;quot;sDark&amp;quot; )&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;// headerRows : integer ( default is 1 )&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;// fixedCols : integer ( default is 0 )&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;// colWidths : integer array ( use -1 for auto sizing )&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;// onStart : function ( any this.variableNameHere variables you create here can be used later ( eg. onFinish function ) )&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;// onFinish : function ( all this.variableNameHere variables created in this script can be used in this function )&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;// margin, padding, width, height, overflow...: Styles for &amp;quot;fakeContainer&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;//&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;////// Example:&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;// $(&amp;quot;#GridView1&amp;quot;).toSuperTable(&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//              { width: &amp;quot;640px&amp;quot;, height: &amp;quot;480px&amp;quot;, fixedCols: 2,&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;//                onFinish: function() { alert(&amp;#39;Done!&amp;#39;); } })&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;(&lt;span class="kwrd"&gt;function&lt;/span&gt;($) {&lt;/pre&gt;&lt;pre&gt;    $.fn.extend(&lt;/pre&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;pre&gt;                toSuperTable: &lt;span class="kwrd"&gt;function&lt;/span&gt;(options) {&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;var&lt;/span&gt; setting = $.extend(&lt;/pre&gt;&lt;pre&gt;                    {&lt;/pre&gt;&lt;pre class="alt"&gt;                        width: &lt;span class="str"&gt;&amp;quot;640px&amp;quot;&lt;/span&gt;, height: &lt;span class="str"&gt;&amp;quot;320px&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;                        margin: &lt;span class="str"&gt;&amp;quot;10px&amp;quot;&lt;/span&gt;, padding: &lt;span class="str"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                        overflow: &lt;span class="str"&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt;, colWidths: undefined,&lt;/pre&gt;&lt;pre&gt;                        fixedCols: 0, headerRows: 1,&lt;/pre&gt;&lt;pre class="alt"&gt;                        onStart: &lt;span class="kwrd"&gt;function&lt;/span&gt;() { },&lt;/pre&gt;&lt;pre&gt;                        onFinish: &lt;span class="kwrd"&gt;function&lt;/span&gt;() { },&lt;/pre&gt;&lt;pre class="alt"&gt;                        cssSkin: &lt;span class="str"&gt;&amp;quot;sSky&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                    }, options);&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.each(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="kwrd"&gt;var&lt;/span&gt; q = $(&lt;span class="kwrd"&gt;this&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;var&lt;/span&gt; id = q.attr(&lt;span class="str"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;                        q.removeAttr(&lt;span class="str"&gt;&amp;quot;style&amp;quot;&lt;/span&gt;).wrap(&lt;span class="str"&gt;&amp;quot;&amp;lt;div id=&amp;#39;&amp;quot;&lt;/span&gt; + id + &lt;span class="str"&gt;&amp;quot;_box&amp;#39;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="kwrd"&gt;var&lt;/span&gt; nonCssProps = [&lt;span class="str"&gt;&amp;quot;fixedCols&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;headerRows&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;onStart&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;onFinish&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;cssSkin&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;colWidths&amp;quot;&lt;/span&gt;];&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;var&lt;/span&gt; container = $(&lt;span class="str"&gt;&amp;quot;#&amp;quot;&lt;/span&gt; + id + &lt;span class="str"&gt;&amp;quot;_box&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; p &lt;span class="kwrd"&gt;in&lt;/span&gt; setting) {&lt;/pre&gt;&lt;pre&gt;                            &lt;span class="kwrd"&gt;if&lt;/span&gt; ($.inArray(p, nonCssProps) == -1) {&lt;/pre&gt;&lt;pre class="alt"&gt;                                container.css(p, setting[p]);&lt;/pre&gt;&lt;pre&gt;                                delete setting[p];&lt;/pre&gt;&lt;pre class="alt"&gt;                            }&lt;/pre&gt;&lt;pre&gt;                        }&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;/pre&gt;&lt;pre&gt;                        &lt;span class="kwrd"&gt;var&lt;/span&gt; mySt = &lt;span class="kwrd"&gt;new&lt;/span&gt; superTable(id, setting);&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;                    });&lt;/pre&gt;&lt;pre class="alt"&gt;                }&lt;/pre&gt;&lt;pre&gt;            });&lt;/pre&gt;&lt;pre class="alt"&gt;})(jQuery);&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;完整的Demo程式如下:&lt;/p&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="asp"&gt;&amp;lt;%@ Import Namespace=&amp;quot;System.Data&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="html"&gt;DOCTYPE&lt;/span&gt; &lt;span class="attr"&gt;html&lt;/span&gt; &lt;span class="attr"&gt;PUBLIC&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        DataTable t = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataTable();&lt;/pre&gt;&lt;pre&gt;        t.Columns.Add(&lt;span class="str"&gt;&amp;quot;序號&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;        t.Columns.Add(&lt;span class="str"&gt;&amp;quot;料號&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;));&lt;/pre&gt;&lt;pre&gt;        t.Columns.Add(&lt;span class="str"&gt;&amp;quot;單價&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;decimal&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 1; i &amp;lt;= 10; i++)&lt;/pre&gt;&lt;pre&gt;            t.Columns.Add(&lt;span class="str"&gt;&amp;quot;庫存&amp;quot;&lt;/span&gt; + i, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;        Random rnd = &lt;span class="kwrd"&gt;new&lt;/span&gt; Random();&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 80; i++)&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            DataRow row = t.NewRow();&lt;/pre&gt;&lt;pre class="alt"&gt;            row[&lt;span class="str"&gt;&amp;quot;序號&amp;quot;&lt;/span&gt;] = i + 1;&lt;/pre&gt;&lt;pre&gt;            row[&lt;span class="str"&gt;&amp;quot;料號&amp;quot;&lt;/span&gt;] = Guid.NewGuid().ToString().Substring(0, 13).ToUpper();&lt;/pre&gt;&lt;pre class="alt"&gt;            row[&lt;span class="str"&gt;&amp;quot;單價&amp;quot;&lt;/span&gt;] = rnd.NextDouble() * 100;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; j = 1; j &amp;lt;= 10; j++)&lt;/pre&gt;&lt;pre class="alt"&gt;                row[&lt;span class="str"&gt;&amp;quot;庫存&amp;quot;&lt;/span&gt; + j] = rnd.Next(10000);&lt;/pre&gt;&lt;pre&gt;            t.Rows.Add(row);            &lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;        GridView1.AutoGenerateColumns = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (DataColumn c &lt;span class="kwrd"&gt;in&lt;/span&gt; t.Columns)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            BoundField bf = &lt;span class="kwrd"&gt;new&lt;/span&gt; BoundField();&lt;/pre&gt;&lt;pre&gt;            bf.DataField = c.ColumnName;&lt;/pre&gt;&lt;pre class="alt"&gt;            bf.HeaderText = c.ColumnName;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (c.DataType == &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;decimal&lt;/span&gt;))&lt;/pre&gt;&lt;pre class="alt"&gt;                bf.DataFormatString = &lt;span class="str"&gt;&amp;quot;{0:#,0.00}&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (c.DataType == &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt;))&lt;/pre&gt;&lt;pre class="alt"&gt;                bf.DataFormatString = &lt;span class="str"&gt;&amp;quot;{0:#,0}&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;            bf.ItemStyle.HorizontalAlign =&lt;/pre&gt;&lt;pre class="alt"&gt;                (!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(bf.DataFormatString)) ?&lt;/pre&gt;&lt;pre&gt;                HorizontalAlign.Right : HorizontalAlign.Center;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;/pre&gt;&lt;pre&gt;            GridView1.Columns.Add(bf);&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;        GridView1.DataSource = t;&lt;/pre&gt;&lt;pre class="alt"&gt;        GridView1.DataBind();&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;lt;html xmlns=&lt;span class="str"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;head runat=&lt;span class="str"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;style type=&lt;span class="str"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    .altRow { background-color: #ddddff; }&lt;/pre&gt;&lt;pre&gt;    &amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;link href=&lt;span class="str"&gt;&amp;quot;superTables.css&amp;quot;&lt;/span&gt; rel=&lt;span class="str"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; type=&lt;span class="str"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; src=&lt;span class="str"&gt;&amp;quot;jquery-1.3.1.js&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; src=&lt;span class="str"&gt;&amp;quot;superTables.js&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; src=&lt;span class="str"&gt;&amp;quot;jquery.superTable.js&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre&gt;        $(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre class="alt"&gt;            $(&lt;span class="str"&gt;&amp;quot;#GridView1&amp;quot;&lt;/span&gt;).toSuperTable({ width: &lt;span class="str"&gt;&amp;quot;640px&amp;quot;&lt;/span&gt;, height: &lt;span class="str"&gt;&amp;quot;480px&amp;quot;&lt;/span&gt;, fixedCols: 2 })&lt;/pre&gt;&lt;pre&gt;            .find(&lt;span class="str"&gt;&amp;quot;tr:even&amp;quot;&lt;/span&gt;).addClass(&lt;span class="str"&gt;&amp;quot;altRow&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;        });&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;form1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:GridView&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GridView1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Font-Size&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;9pt&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;EnableViewState&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:GridView&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/4239/500x375.aspx" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;我放了一個線上Demo在&lt;a href="http://www.darkthread.net/MiniAjaxLab/ScrollTable"&gt;http://www.darkthread.net/MiniAjaxLab/ScrollTable&lt;/a&gt; ，或者你也可以下載&lt;a href="http://www.darkthread.net/MiniAjaxLab/ScrollTable/ScrollTableDemo.zip"&gt;程式包&lt;/a&gt;回去玩。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Keywords&lt;/b&gt;: fixed column, fixed header, freeze, scroll, excel, datagrid, gridview, html table, plugin, jQuery&lt;/p&gt;&lt;p&gt;&lt;font color="#ff6600"&gt;[2010-07-26補充]&lt;/font&gt; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;to 各位網友，關於Super 
Table，陸續累積了好多網友的提問，不過坦白跟大家說，當初為要動用這個技術解決的工作需求，受限於Javascript在表格欄位超多時的捲動效能
表現無法符合User需求，最後還是決定改用Silverlight實作... 因此這部分並未深入嘗試繼續研究了。&lt;/p&gt;
&lt;p&gt;我仍有興趣解決一些&amp;quot;小幅修改JS就能克服&amp;quot;的問題，但前題必須要請大家提供&amp;quot;可以示範問題所在的實際網頁範例&amp;quot;，才好射茶包。Super Table所使用的技巧蠻Hacking的，若能簡單滿足需求很好，若必須大幅改造才能適用，我倒覺值得評估一下。(純個人意見)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=4240" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>GridView的標題列凍結效果</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/17/gridview-fixed-header.aspx</link><pubDate>Tue, 17 Feb 2009 05:37:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:4230</guid><dc:creator>Jeffrey</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=4230</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/17/gridview-fixed-header.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;
&lt;p&gt;應該有不少人被這麼要求過吧? &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;你們做的網頁表格為什麼不能像Excel一樣凍結標題列，底下捲來捲去也不會跑掉?&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;前陣子看到一個不錯的Javascript Library，只用一行Code就可以輕鬆做出HTML表格列凍結的效果，剛好部門裡也常有這種需求，我就弄了一個簡單的範例。&lt;/p&gt;
&lt;p&gt;大家可以先看&lt;a href="http://www.webtoolkit.info/scrollable-html-table-plugin-for-jquery.html"&gt;Scrollable HTML Table Plugin&lt;/a&gt;的&lt;a href="http://www.webtoolkit.info/demo/jquery/scrollable/demo.html"&gt;範例&lt;/a&gt;，它本來是個&lt;a href="http://www.webtoolkit.info/scrollable-html-table.html"&gt;純Javascript Library&lt;/a&gt;，Plugin只是做了簡單的包裝，把new ScrollableTable()一列指令再包起來，意義不大，所以我的示範裡只使用webtoolkit.scrollabletable.js，省去額外載入webtoolkit.jscrollable.js的功夫。&lt;/p&gt;
&lt;p&gt;弄了一個虛構的DataTable，Bind到GridView上，稍作處理再var t = new ScrollableTable($(&amp;quot;#GridView1&amp;quot;)[0], 400, 640);，就變成以下的樣子:&lt;/p&gt;
&lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/4229/500x375.aspx" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;完整程式碼如下:&lt;/p&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="asp"&gt;&amp;lt;%@ Import Namespace=&amp;quot;System.Data&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="html"&gt;DOCTYPE&lt;/span&gt; &lt;span class="attr"&gt;html&lt;/span&gt; &lt;span class="attr"&gt;PUBLIC&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        DataTable t = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataTable();&lt;/pre&gt;&lt;pre&gt;        t.Columns.Add(&lt;span class="str"&gt;&amp;quot;序號&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;        t.Columns.Add(&lt;span class="str"&gt;&amp;quot;料號&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;));&lt;/pre&gt;&lt;pre&gt;        t.Columns.Add(&lt;span class="str"&gt;&amp;quot;單價&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;decimal&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;        t.Columns.Add(&lt;span class="str"&gt;&amp;quot;數量&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt;));&lt;/pre&gt;&lt;pre&gt;        t.Columns.Add(&lt;span class="str"&gt;&amp;quot;金額&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;decimal&lt;/span&gt;), &lt;span class="str"&gt;&amp;quot;單價*數量&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;        Random rnd = &lt;span class="kwrd"&gt;new&lt;/span&gt; Random();&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 200; i++)&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            t.Rows.Add(&lt;/pre&gt;&lt;pre class="alt"&gt;                i + 1, &lt;/pre&gt;&lt;pre&gt;                Guid.NewGuid().ToString().Substring(0, 13).ToUpper(),&lt;/pre&gt;&lt;pre class="alt"&gt;                rnd.NextDouble() * 100,&lt;/pre&gt;&lt;pre&gt;                rnd.Next() * 2000);&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;        GridView1.AutoGenerateColumns = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (DataColumn c &lt;span class="kwrd"&gt;in&lt;/span&gt; t.Columns)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            BoundField bf = &lt;span class="kwrd"&gt;new&lt;/span&gt; BoundField();&lt;/pre&gt;&lt;pre&gt;            bf.DataField = c.ColumnName;&lt;/pre&gt;&lt;pre class="alt"&gt;            bf.HeaderText = c.ColumnName;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (c.DataType == &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;decimal&lt;/span&gt;))&lt;/pre&gt;&lt;pre class="alt"&gt;                bf.DataFormatString = &lt;span class="str"&gt;&amp;quot;{0:#,0.00}&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (c.DataType == &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt;))&lt;/pre&gt;&lt;pre class="alt"&gt;                bf.DataFormatString = &lt;span class="str"&gt;&amp;quot;{0:#,0}&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;            bf.ItemStyle.HorizontalAlign =&lt;/pre&gt;&lt;pre class="alt"&gt;                (!&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(bf.DataFormatString)) ?&lt;/pre&gt;&lt;pre&gt;                HorizontalAlign.Right : HorizontalAlign.Center;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;/pre&gt;&lt;pre&gt;            GridView1.Columns.Add(bf);&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;        GridView1.DataSource = t;&lt;/pre&gt;&lt;pre class="alt"&gt;        GridView1.DataBind();&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;lt;html xmlns=&lt;span class="str"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;head runat=&lt;span class="str"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;style type=&lt;span class="str"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    #GridView1 tr { border: solid 1px #f0f0f0; }&lt;/pre&gt;&lt;pre&gt;    #GridView1 td, th { padding: 3px; border: solid 1px white; }&lt;/pre&gt;&lt;pre class="alt"&gt;    td, th { padding: 3px; border: solid 1px white; }&lt;/pre&gt;&lt;pre&gt;    #GridView1 thead tr { background-color: #dddddd; }&lt;/pre&gt;&lt;pre class="alt"&gt;    .altRow { background-color: #ddddff; }&lt;/pre&gt;&lt;pre&gt;    &amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; src=&lt;span class="str"&gt;&amp;quot;jquery-1.3.1.js&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; src=&lt;span class="str"&gt;&amp;quot;webtoolkit.scrollabletable.js&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre&gt;        $(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre class="alt"&gt;            $(&lt;span class="str"&gt;&amp;quot;#GridView1 tr:first&amp;quot;&lt;/span&gt;).wrap(&lt;span class="str"&gt;&amp;quot;&amp;lt;thead&amp;gt;&amp;lt;/thead&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            $(&lt;span class="str"&gt;&amp;quot;#GridView1 thead&amp;quot;&lt;/span&gt;).insertBefore(&lt;span class="str"&gt;&amp;quot;#GridView1 tbody&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            $(&lt;span class="str"&gt;&amp;quot;#GridView1 tbody tr:odd&amp;quot;&lt;/span&gt;).addClass(&lt;span class="str"&gt;&amp;quot;altRow&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            $(&lt;span class="str"&gt;&amp;quot;#GridView1&amp;quot;&lt;/span&gt;).attr(&lt;span class="str"&gt;&amp;quot;cellspacing&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; t = &lt;span class="kwrd"&gt;new&lt;/span&gt; ScrollableTable($(&lt;span class="str"&gt;&amp;quot;#GridView1&amp;quot;&lt;/span&gt;)[0], 400, 640);&lt;/pre&gt;&lt;pre&gt;        });&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;form1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:GridView&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GridView1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Font-Size&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;9pt&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:GridView&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;由於Scrollable HTML Table需要由&amp;lt;thead&amp;gt;, &amp;lt;tbody&amp;gt;區分凍結區及捲動區，而GridView所產生的HTML Table標題列及內容列都放在&amp;lt;tbody&amp;gt;中且無&amp;lt;thead&amp;gt;，因此要做些事後加工，將標題列提取出來，另外放入新增的&amp;lt;thead&amp;gt;中，程式示範了如何jQuery wrap, insertBefore來解決這個問題，都是酷酷地一步到位，蠻值得參考的。&lt;/p&gt;
&lt;p&gt;&lt;font style="BACKGROUND-COLOR:#ffff99;" color="#ff0000"&gt;注意: 此解決方案無法跨瀏覽器，目前測試只有IE6, IE7, FF3可用, 不支援IE8, Safari, Chrome, Opera。&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="BACKGROUND-COLOR:#ffcc99;" color="#ff0000"&gt;【2009-02-18 更新】找到另一個跨瀏覽器且支援標題欄、列凍結的版本，請見: &lt;/font&gt;&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/18/supertable-plugin-for-jquery.aspx"&gt;&lt;font style="BACKGROUND-COLOR:#ffcc99;" color="#0000ff"&gt;GridView的標題欄、列凍結效果(跨瀏覽器版)&lt;/font&gt;&lt;/a&gt;&lt;font style="BACKGROUND-COLOR:#ffcc99;" color="#ff0000"&gt; &lt;/font&gt;&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=4230" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>CODE-用Javascript刪除ASP.NET寫入的Cookie</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/06/delete-asp-net-cookie-by-js.aspx</link><pubDate>Thu, 05 Feb 2009 22:03:06 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:4149</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=4149</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/06/delete-asp-net-cookie-by-js.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;今天要挑戰的是用Javascript刪除ASP.NET寫入的Cookie。&lt;/p&gt; &lt;p&gt;Client-Side本來就可以由document.cookie取得Cookie，其為一字串，格式類似cookie1=value1;cookie2=value2;cookie3=value3，要用得自行拆解，但不乏現成的共用函數可以代勞。若網頁有引用jQuery，&lt;a href="http://plugins.jquery.com/project/Cookie"&gt;jQuery Cookie Plugin&lt;/a&gt;是不錯的選擇。&lt;/p&gt; &lt;p&gt;要用jQuery Cookie Plugin刪除Cookie可以寫成$.cookie(&amp;quot;CookieName&amp;quot;, null);，但如果要刪除ASP.NET寫入的Cookie，必須要提供與Server端寫入時完全一致的Path、Domain、Expires才能成功。因此後方的範例程式中，刪除未設有效期限的Cookie，至少要傳入Path=&amp;quot;/&amp;quot;，例如: $.cookie(&amp;quot;MyCookie&amp;quot;, null, { path:&amp;quot;/&amp;quot; });，由於ASP.NET未指定Domain，Client-Side可以傳domain:&amp;quot;&amp;quot;或逕行省略。&lt;/p&gt; &lt;p&gt;如果當初寫入Cookie時有設定Expires就比較麻煩些，因為Cookie的細節資訊(如有效期限)只保存在Browser裡，並不會隨Request送回Server，因此Server端連用Request.Cookies[&amp;quot;CookieName&amp;quot;].Expires讀不到當初指定的有效期限(讀到的永遠都是0001/01/01 00:00:00)，更甭提Javascript了。除非Javascript端能掌握正確的Expires(透過Hidden傳回前端，或採用事先約定的邏輯，不然就得筊杯了)，否則就無法將Cookie刪除。在以下的範例中，驗證了只要Expires指定正確，有設期限的Cookie還是可以被刪除的(例如: AbsExprCookie)。&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!Page.IsPostBack)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//不設期限&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            Response.Cookies.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; HttpCookie(&lt;span class="str"&gt;&amp;quot;MyCookie&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Darkthread&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//設相對期限&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            HttpCookie c = &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpCookie(&lt;span class="str"&gt;&amp;quot;RelExprCookie&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Darkthread&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            c.Expires = DateTime.Now.AddMinutes(10d);&lt;/pre&gt;&lt;pre&gt;            Response.Cookies.Add(c);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//設絕對期限&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            c = &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpCookie(&lt;span class="str"&gt;&amp;quot;AbsExprCookie&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Darkthread&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            c.Expires = DateTime.ParseExact(&lt;span class="str"&gt;&amp;quot;2009/02/28&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;yyyy/MM/dd&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            Response.Cookies.Add(c);&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnCheckCookie_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        StringBuilder sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder(&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="str"&gt;&amp;quot;Cookies Count=&amp;quot;&lt;/span&gt; + Request.Cookies.Count.ToString() + &lt;span class="str"&gt;&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; ck &lt;span class="kwrd"&gt;in&lt;/span&gt; Request.Cookies.Keys)&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            HttpCookie c = Request.Cookies[ck];&lt;/pre&gt;&lt;pre class="alt"&gt;            sb.AppendFormat(&lt;/pre&gt;&lt;pre&gt;                &lt;span class="str"&gt;&amp;quot;&amp;lt;li&amp;gt;[{0}]={1}&amp;lt;br /&amp;gt;Path={2}, Domain={3}, Expires={4}&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                c.Name, c.Value, c.Path, c.Domain, c.Expires);&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;        lblDisp.Text = sb.ToString();&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;lt;html xmlns=&lt;span class="str"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;head runat=&lt;span class="str"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;title&amp;gt;Cookie Test&amp;lt;/title&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; src=&lt;span class="str"&gt;&amp;quot;../js/jquery-1.3.1.js&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; src=&lt;span class="str"&gt;&amp;quot;../js/jquery.cookie.js&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        $(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (document.cookie &amp;amp;&amp;amp; document.cookie != &lt;span class="str"&gt;&amp;#39;&amp;#39;&lt;/span&gt;) {&lt;/pre&gt;&lt;pre class="alt"&gt;                $(&lt;span class="str"&gt;&amp;quot;#dvDisp&amp;quot;&lt;/span&gt;).html(&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="str"&gt;&amp;quot;&amp;lt;li&amp;gt;&amp;quot;&lt;/span&gt; + document.cookie.replace(/;/g, &lt;span class="str"&gt;&amp;quot;&amp;lt;li&amp;gt;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;                );&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            $(&lt;span class="str"&gt;&amp;quot;#btnDelCookie&amp;quot;&lt;/span&gt;).click(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;                $.cookie(&lt;span class="str"&gt;&amp;quot;MyCookie&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, { path:&lt;span class="str"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; });&lt;/pre&gt;&lt;pre class="alt"&gt;                $.cookie(&lt;span class="str"&gt;&amp;quot;AbsExprCookie&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;                    { path:&lt;span class="str"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;, expires: &lt;span class="kwrd"&gt;new&lt;/span&gt; Date(2009, 2, 28) });&lt;/pre&gt;&lt;pre class="alt"&gt;                alert(&lt;span class="str"&gt;&amp;quot;Cookies deleted!&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            });&lt;/pre&gt;&lt;pre class="alt"&gt;        });&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/css&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    body, html { font-size: 9pt; padding: 5px; }&lt;/pre&gt;&lt;pre class="alt"&gt;    fieldset { height:150px; width: 300px; &lt;/pre&gt;&lt;pre&gt;               text-align: left; padding: 10px;}&lt;/pre&gt;&lt;pre class="alt"&gt;    .fldDiv { background-color: #dddddd; margin-top: 20px; &lt;/pre&gt;&lt;pre&gt;              width:330px; height: 180px; text-align:center;}&lt;/pre&gt;&lt;pre class="alt"&gt;    #btnDelCookie { color: Blue; text-decoration: underline;&lt;/pre&gt;&lt;pre&gt;                    cursor: pointer; }&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;form1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:Button&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;btnCheckCookie&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Check Cookie&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="attr"&gt;onclick&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;btnCheckCookie_Click&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;fldDiv&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;fieldset&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;legend&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Server View&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;legend&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:Label&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;lblDisp&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;N/A&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:Label&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;fieldset&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;fldDiv&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;fieldset&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;legend&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Client View&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;legend&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;dvDisp&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;fieldset&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;span&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;btnDelCookie&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Delete Cookie&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;span&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;網頁跑起來如下圖，Delete Cookie按鈕可以刪除MyCookie及AbsExprCookie，RelExprCookie的有效期限對Javascript來說是個謎，無從刪起。刪除後按下Check Cookie，Server端會發現那個兩Cookie不見了，表示刪除成功。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/4144/original.aspx" alt="" /&gt;&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=4149" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>CODE-定時自動更新的UpdatePanel</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/12/11/updatepanel-with-timer.aspx</link><pubDate>Thu, 11 Dec 2008 20:21:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:3932</guid><dc:creator>Jeffrey</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=3932</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/12/11/updatepanel-with-timer.aspx#comments</comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;
&lt;p&gt;雖然上回已明白揭示過UpdatePanel&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/11/26/why-not-updatepanel.aspx"&gt;傳輸效率不佳&lt;/a&gt;的事實，剛好有同事請我提供網頁部分內容定期自動更新的範例。想了一下，UpdatePanel還是最佳的解決方案，理由是:&lt;/p&gt;
&lt;ol&gt;
&lt;ol&gt;
&lt;li&gt;開發人員較少Javascript的開發經驗，但ASPX經驗豐富。 
&lt;li&gt;該網頁使用者人數不多，更新頻率不高(約一分鐘一次)。 
&lt;li&gt;需求很急迫，不是學新東西的好時機，希望使用的技術愈簡單愈易實作愈好。&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;
&lt;p&gt;符合上述條件的技術選項，毋庸置疑，非UpdatePanel莫屬!! (再次證明，&amp;quot;沒有一無是處的技術，只有用錯場合的白目&amp;quot;)&lt;/p&gt;
&lt;p&gt;我寫了以下的範例，用一個UpdatePanel包住Label1，另外放了一個Timer1，設定一秒Tick一次，至於UpdatePanel，當然就用Timer1的Tick作為觸發事件，更新Label1.Text就寫在Timer1_Tick裡。另外，我設了按鈕可以透過CSS display屬性決定UpdatePanel顯示與否，驗證隱藏時會持續更新。(為求單純化，我連jQuery都沒拉進來)&lt;/p&gt;
&lt;p&gt;&lt;img alt="UpdatePanel With Timer" src="http://blog.darkthread.net/photos/darkthread/images/3931/original.aspx" /&gt;&lt;/p&gt;
&lt;p&gt;程式碼如下，給有需要的人參考吧!&lt;/p&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Timer1_Tick(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        Label1.Text = DateTime.Now.ToString();&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;form1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ScriptManager1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;button&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Show&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="attr"&gt;onclick&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;$get(&amp;#39;dvDisp&amp;#39;).style.display=&amp;#39;block&amp;#39;;&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;button&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Hide&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="attr"&gt;onclick&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;$get(&amp;#39;dvDisp&amp;#39;).style.display=&amp;#39;none&amp;#39;;&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;dvDisp&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdatePanel1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:Label&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Label1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Label&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:Label&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ContentTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Triggers&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:AsyncPostBackTrigger&lt;/span&gt; &lt;span class="attr"&gt;ControlID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Timer1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;EventName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Tick&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Triggers&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:Timer&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Timer1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre&gt;&lt;span class="attr"&gt;ontick&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Timer1_Tick&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Interval&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1000&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:Timer&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=3932" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item></channel></rss>