2007年11月29日
Machine Name有underline時,Session會掉
而登入帳號我們是存在Session中的,後來去將它的SessionID Response出來,發現,怎麼SessionID會一值變動呢?
後來又將它原本的Machine Name拿掉,改用IP去連,結果竟然OK了!
經過一番的折騰之後,中於在微軟的KB上發現這一篇!
http://support.microsoft.com/kb/316112/zh-tw
內容簡略如下:
防止伺服器以不正確的名稱語法來設定 Cookie 名稱。使用 Cookie 的網域在網域名稱和伺服器名稱中,一定只能使用英數字元 ("-" 或 ".")。如果伺服器名稱包含其他字元,例如底線字元 ("_"),Internet Explorer 會阻擋來自該伺服器的 Cookie。
沒錯,一開始我們使用的Machine Name就是有包含底線摟~~
建議解決方法:
• 重新命名網域名稱和伺服器名稱,而且只使用英數字元。
• 使用「網際網路通訊協定」(IP) 位址 (而不要用網域/伺服器名稱) 來瀏覽至伺服器。
就是這麼一回事摟~~~
2007年11月28日
icon搜尋網 - iconlet.com
2007年11月27日
大陸網路鎖Blogger
但是一直很令我那悶的是,在這廣大市場的大陸中,為何一直沒有人連上來呢?
是因為大陸網友給的資料已經夠多了,不需要台灣的網友提供的資料嗎?
還是其他原因呢?一直沒有找到答案,剛剛心血來潮,就請了在大陸的朋友,幫我用大陸網路,連連我的Blog看看,
果真沒錯,跟我猜測的一樣,大陸網路封鎖了Bloger網域啦!
天阿~~我不想放棄這一廣大的市場啦!
有誰可以給我解法呢?
2007年11月26日
Checking your address on Google Maps
Google Maps已經有開放商家刊登住址與位址了!但是有時候難免會有對應錯誤的時候!
這時候可能會造成使用者誤導的情形(http://www.richyli.com/blog/2007/11/google-map.html)
也因為這樣的原因,所以Google就秉持著Web 2.0的概念,開放使用者可以修正Google Maps上的資訊位址摟~~
利用Web 2.0的經營概念,來讓Google Maps資料的正確性更往上提升了!
不過聽說目前尚未全區開放,只有進行某些區域的逐步開發,相信不久之後,台灣的網友們也可以修正自家附近的商家位址摟~~~
工程師看SilverLight
但是經過一番了解之後,我發覺,應該說看我們怎麼去應用它吧!
我們或許可以應用它來開發出一個UI,然後再交給美工去做一些比較完美的配色跟特效。
過去如果我們純用ASP.NET去撰寫的話,要再請美工近來修改畫面或是操作介面,似乎很困難,因為要改Code。
而有了SilverLight我期待它可以解決這方面的問題,美工人員可以直接透過介面,就可以設定了,不用改任何的程式碼。
或許這就是新的應用吧!
下面是我在YouTube找到的一些展示影片,讓各位體驗一下他的威力,也讓Programer的你我他,知道它並非只是單純美工該做的事情而已!
Silverlight - Microsoft RIA的技術解決方案
所以就將它轉載過來給各位瞧瞧這不錯的新技術!
| Silverlight搶先預覽(1)微軟的RIA技術銀光乍現 | ||
| 文/iThome (記者) 2007-05-10 | ||
| 所謂的RIA是以向量為基礎、具備動畫能力,可以展現優越影音多媒體能力的應用。相關技術不是以Adobe的Flash為基底,就是以微軟Silverlight為基底。 | ||
| | ||
| 微軟2007年4月16日透過全國廣播協會(NAB)宣布WPF/E正式命名為「Silverlight」。
|
2007年11月25日
Div字數太多,破壞原本版面設計 - overflow (Width = 100%) (IE : word-break firefox : overflow)
這個問題往往大家都是用overflow的CSS屬性就可以解決了。
下面這裡有一些微軟官方資料可以參考看看:
http://msdn2.microsoft.com/en-us/library/ms534312.aspx
http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/overflow.htm
但是問題如果可以這麼簡單就解決的話,我就不用另外說明了。
當我們的div有設定一個寬度(width)的話,而且該寬度是一個固定的像素,例如500px等等的,
這樣就好辦,毫無問題。(不管是在firefox上或是在IE上面,都可以正常運作。)
但是問題來了,當我們設定它的Width為100%時,Firefox上~~OK,正常執行,但是IE呢?真的只能用OOXX來形容摟~~
為了這個問題我尋找了一天一夜,找到了一個替代方案,感覺還不錯!
我將DIV的Style設定為下面這一個:
style='word-break:break-all; overflow:auto;'
word-break是指能夠在IE上跑,而overflow當寬度設定為100%時,可以在firefox上跑!
如此這兩個屬性搭配,將可以讓我們的版面,可以當寬度超過時,自動換行,不會擠壓到版面。
不過在IE上面就不會長ScrollBar就是了!
Try it.
miniMIZE:把視窗變縮圖的工具
下面是這個Blog的內容:

miniMIZE 是一個相當有趣味的 Windows 軟體,功能也相當的簡單,下載安裝過後啟動這個軟體縮小視窗,會發現視窗縮小到桌面上了,並且以縮圖配合軟體圖案的方式呈現出來,就像是把視窗擺在桌面上一樣,程式原本出現在工作列的按鈕也會被隱藏起來,大大節省了工作列的使用空間,上班偷上 BBS 時也很好用。:P
視窗縮圖出現在桌面上後,可以拖拉放到自己想要的位置;縮小後的視窗可設定顯示最上層、與正常視窗排列先後,也可以只在桌面層出現,相當的方便,尤其是在視窗很多全都縮小後更易於整理與觀看要開啟哪個視窗來作業。檔案程式相當的小,執行後佔據記憶體約 5MB 左右。官網、下載。
底下是執行後視窗縮小到桌面的情況:
2007年11月22日
diggirl
而我發現我身邊的男性友人,它們的iGoogle中,最常出現的第一名是新聞,而第二名就是diggirl了!
也因為這樣的因緣際會下,再加上它內容物的吸引下... >< 所以我稍微研究了一下它是甚麼東西。
根據Mr. 6的介紹中得知,diggirl是業界知名的專案開發老手兼文筆雄健的業餘作家「獨孤木」所領導開發出來的,
主要的經營型態是藉由使用者瀏覽美女圖後分享,再透過會員的潤飾產生一份較完整的資料庫(Web2.0 的運作模式),讓 Diggirl 區分出 Hot、New、Random 等選項讓想看想圖的人可以依喜好去瀏覽。
在Mr. 6的介紹diggirl的文章中,我看到了也發現了一些東西,原來這就是所謂的Web 2.0的創業模式!
記得在數個月前,曾經跟我的學長聊天,提到這一個網站,他戲稱這是一個Web 2.0的"色情網站"(他後續說這是網友們的誤解。)
不過從這個網站的發展經過,我們不難發現,Web 2.0的應用模式,真的無奇不有
而到底要如何在Web 2.0的這片紅海中闖出一片名堂呢?
我想無庸置疑的就是『創意』與『創新』了,想別人還沒有想到的東西,做別人還不感興趣的東西,
或許就是所謂的藍海策略吧?

當初成立這個Blog的想法就是希望藉由它來慢慢的讓自己找到一些Web 2.0中可以發展的新idea,也希望藉由它可以讓我找到一些夥伴,一同在Web 2.0中,創造另外一個藍海的市場...
看到了這個成功的案例,給了我一劑強心針,讓我對一開始的想法更有信心。
也希望有同好的朋友,不管是哪一方面的idea,我們都可以一起來創造它的藍海市場。
加油吧!Mr. NFrankenstein的團隊們...
2007年11月21日
在UpdatePanel下,使用RegisterClientScript
將其相對應的功能列表於下:
RegisterArrayDeclaration
使用陣列名稱和陣列值,向 Page 物件註冊 JavaScript 陣列宣告。
ScriptManager.RegisterArrayDeclaration(UpdatePanel1,"Hello",,"1,2,3");RegisterClientScriptBlock
向Page物件註冊用戶端指令碼。最後一個參數若為true,則會自動加上<script></script>
ScriptManager.RegisterClientScriptBlock(UpdatePanel1,this.GetType(), "HelloWorld", "function helloWorld(){alert(1);}", true);RegisterClientScriptInclude
向 Page 物件註冊用戶端指令碼 Include。
ScriptManager.RegisterClientScriptInclude(UpdatePanel1,this.GetType(),"HelloWorld",Server.MapPath("test.js"));RegisterClientScriptResource
使用型別和資源名稱,向 Page 物件註冊用戶端指令碼資源。
ScriptManager.RegisterClientScriptResource(UpdatePanel1,this.GetType(),"test.js");RegisterExpandoAttribute
將名稱/值組註冊為指定之控制項的自訂 (Expando) 屬性
ScriptManager.RegisterExpandoAttribute(UpdatePanel1,Button1.ClientID,"attributeName","attributeValue",trueRegisterHiddenField
向 Page 物件註冊隱藏值
ScriptManager.RegisterHiddenField(UpdatePanel1,"hiddenFieldName", "hiddenFieldIntialValueRegisterOnSubmitStatement
使用類型、索引鍵和指令碼常值 (Literal),向 Page 物件註冊 OnSubmit 陳述式。當送出
HtmlForm 時,會執行該陳述式
ScriptManager.RegisterOnSubmitStatement(UpdatePanel1,this.GetType(),"test","return window.confirm('test'))RegisterStartupScript
向 Page 物件註冊啟始指令碼
ScriptManager.RegisterStartupScript(UpdatePanel1,this.GetType(),"HelloWorld", "alert('The page has loaded!')",true);除了利用上面這一些Method將Script註冊到Client外,在UpdatePanel的AsyncPostBack啟動前後都可以加上一個Script Function,會先去呼叫該Function,然後才去做AsyncPostBack。語法如下:
Me.Page.ClientScript.RegisterStartupScript(Me.GetType,"AjaxBeforeUpdatePanelLoad", "<script type='text/javascript'>Sys.WebForms.PageRequestManager.getInstance).add_initializeRequest(BeforeUpdatePanelLoad);</script>")Me.Page.ClientScript.RegisterStartupScript(Me.GetType,"AjaxAfterUpdatePanelLoad", "<script type='text/javascript'>Sys.WebForms.PageRequestManager.getInstance).add_endRequest(AfterUpdatePanelLoad);</script>")這樣一來我們就可以自己寫BeforeUpdatePanelLoad和AfterUpdatePanelLoad去做一些我們想要統一做的Script
2007年11月20日
HTML Editor - NVU
但是你知道嗎?它還有其它的免費軟體提供唷...
最近因為需要用到一些HTML的編輯軟體,發現電腦裡面沒有FrontPage,所以就用了Dreamweaver來寫,但是發現,雖然他們的功能強大,但是每次開啟軟體的時間當相當的長,有時候只是想利用HTML Editor來找到配色的代碼而已。也要等上數十秒才能開啟工具使用。
也因為如此,所以我尋找了一下看有沒有一些比較輕量級的Html Editor可以使用。
找著找著,就發現了它 - NVU
NVU 是一套同樣以 Mozilla 為核心的網頁編輯器 (就像市面上常見的 FrontPage 或是 Dreamweaver 等等網頁編輯程式), 目前由 Linspire (以前的 Lindows) 主導開發。
功能可以說是相當的齊全,應有盡有。
若你不想在你電腦上灌一些五四三的軟體,而且你是用Windows作業系統的話,那你可以直接下載壓縮檔。
解開壓縮檔後,直接直接就可以使用摟~~
檔案大小大約只有20MB左右。
下面這個是它的官方網站,有興趣的網友可以上去看看摟~~~
http://www.moztw.org/nvu/
2007年11月16日
gPhone Android Demo Video
大家都以為Google要出自己的手機了,其實並不是的,它的野心感覺更大,並非僅僅如此而已...
未來只要是搭載 Android 作業系統 的手機,都可以稱之為gPhone家族的成員,不論你的手機是哪一家廠商製造的。
下面這一段是影片是Google示範了一段 Android 的基本樣子與一些基本功能,由 Google 創辦人 Sergey Brin 親自開場。
感覺上畫面相當的簡潔...速度感也相當不錯!
2007年11月15日
什麼是Web 2.0 ?
這是一個問句,不僅僅問各位,也同時問我自己...
這個名詞在最近幾年被廣泛的被炒作...
但是當大家都是談論Web 2.0的同時,我疑問的問自己?它到底是甚麼東西呢?它所強調的是甚麼?
一種新技術?還是一種新概念呢?也因為自己的對於它的無知,所以開始上網找一些資料,讓自己更能夠了解它...
而為了不讓這些非常有意義的資料就此僅停留在我的腦海中而已,因此特別將它整理下來。讓各位也有機會去看看這一些寫的相當不錯的文章。
來真正的認識Web 2.0...
http://www.itmag.org.tw/magazine/article_single_138.htm
http://www.itmag.org.tw/magazine/article_single_234.htm
2007年11月14日
jQuery影片
一些它的簡單教學,大師們的談話等等的。
特別將它post出來,讓各位想要使用JavaScript Framework的人,可以參考看看!
或許可以幫助你決定是否使用它吧!
利用JavaScript關閉ASP.NET的Validators
但是有時候我們又要因為使用者輸入了某些字元之後,我們就不進行驗證了,
所以就必須用到使用JavaScript來將Validator關閉了!
最近看到一個不錯的JavaScript的Library,可以很方便的幫助我們關閉他唷!
下面是它的Library,先將它Copy下來,然後存成.js檔後,include進入網頁就可以大方的使用摟~~
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
//Description:
// ValidationDefeater is a scipt file that provides the functionality to have more controle
// over ASP.NET 1.1 validation facilities.
//Author:
// Muhammad Shehabeddeen
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Contained Validators (No ControlToValidate)
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Changes the status of validation to [status] of all child controls of [control] if
// [control] is not null. If [control] is null, [status] is set for all validators.
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
function traverseTree(status, control)
{
if(control == null)
{
for(var i = 0; i < Page_Validators.length; i++)
{
Page_Validators[i].enabled = status;
Page_Validators[i].style.display = status ? 'inline' : 'none';
}
}
else
{
//this is a way to check that the control is a validation control
if(control.evaluationfunction != null)
{
control.enabled = status;
control.style.display = status ? 'inline' : 'none';
}
for( var i=0; i < control.childNodes.length; i++)
{
traverseTree(status, control.childNodes[i]);
}
}
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Looks inside the control having [containerID] as its ID for all validators and enables them.
// If [containerID] is null (not provided) then all validators are enabled.
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
function enableValidators(containerID)
{
var control;
if(containerID == null)
{
control = null;
}
else
{
control = document.getElementById(containerID);
}
if( containerID == null || control != null )
traverseTree(true, control);
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Looks inside the control having [containerID] as its ID for all validators and disables them.
// If [containerID] is null (not provided) then all validators are disabled.
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
function disableValidators(containerID)
{
var control;
if(containerID == null)
{
control = null;
}
else
{
control = document.getElementById(containerID);
}
if( containerID == null || control != null )
traverseTree(false, control);
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// END Contained Validators (No ControlToValidate)
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Contained Validators With ControlToValidate
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Changes the status of validation to [status] of all child controls of [control] that
// have ControlToValidate of value [controlToValidateID]
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
function traverseTreeCTV(status, controlToValidateID, control)
{
if(control == null)
{
for(var i = 0; i < Page_Validators.length; i++)
{
if(Page_Validators[i].controltovalidate != null &&
Page_Validators[i].controltovalidate == controlToValidateID)
{
Page_Validators[i].enabled = status;//disable validator
Page_Validators[i].style.display = status ? 'inline' : 'none';
}
}
}
else
{
if(control.controltovalidate != null && control.controltovalidate == controlToValidateID)
{
control.enabled = status;//disable validator
control.style.display = status ? 'inline' : 'none';
}
for( var i=0; i < control.childNodes.length; i++)
{
traverseTreeCTV(status, controlToValidateID, control.childNodes[i]);
}
}
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Looks inside the control having [containerID] as its ID for any validators that have the
// ControlToValidate property of value [controlToValidateID] and enables them. So it enables validators of
// [controlToValidateID] inside [containerID].
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
function enableCTVValidators(controlToValidateID, containerID)
{
var control;
if(containerID == null)
{
control = null;
}
else
{
control = document.getElementById(containerID);
}
if( containerID == null || control != null )
traverseTreeCTV(true, controlToValidateID, control );
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Looks inside the control having [containerID] as its ID for any validators that have the
// ControlToValidate property of value [controlToValidateID] and disables them. So it disables validators of
// [controlToValidateID] inside [containerID].
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
function disableCTVValidators(controlToValidateID, containerID)
{
var control;
if(containerID == null)
{
control = null;
}
else
{
control = document.getElementById(containerID);
}
if( containerID == null || control != null )
traverseTreeCTV(false, controlToValidateID, control );
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// END Contained Validators With ControlToValidate
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Group Validators
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Looks for all validators having a groupID of [groupID] and sets their status to [status]
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
function setGroupValidatorsStatus(groupID, status)
{
for(var i = 0; i < Page_Validators.length; i++)
{
if(Page_Validators[i].attributes['groupID'].value == groupID)
{
Page_Validators[i].enabled = status;
Page_Validators[i].style.display = status ? 'inline' : 'none';
}
}
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Enables all validators having a groupID of [groupID]
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
function enableGroupValidators(groupID)
{
setGroupValidatorsStatus(groupID, true)
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Disables all validators having a groupID of [groupID]
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
function disableGroupValidators(groupID)
{
setGroupValidatorsStatus(groupID, false)
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// END Group Validators
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// Show/Hide
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
//hides Validators but does not disable them
function hideValidators(containerID)
{
var control;
if(containerID == null)
{
control = null;
}
else
{
control = document.getElementById(containerID);
}
if( containerID == null || control != null )
traverseTreeShowHide(false, control);
}
//shows validators but does not enable them
function showValidators(containerID)
{
var control;
if(containerID == null)
{
control = null;
}
else
{
control = document.getElementById(containerID);
}
if( containerID == null || control != null )
traverseTreeShowHide(true, control);
}
function traverseTreeShowHide(status, control)
{
if(control == null)
{
for(var i = 0; i < Page_Validators.length; i++)
{
Page_Validators[i].style.display = status ? 'inline' : 'none';
}
}
else
{
//this is a way to check that the control is a validation control
if(control.evaluationfunction != null)
{
control.style.display = status ? 'inline' : 'none';
}
for( var i=0; i < control.childNodes.length; i++)
{
traverseTreeShowHide(status, control.childNodes[i]);
}
}
}
//hides the containerID control and if [alsoDisable] is true all validators inside are disabled.
//If the containerID is not supplied, then all validators in the page are hidden.
function hide(alsoDisable, containerID )
{
if(alsoDisable == null)
alsoDisable = false;
var container;
if(containerID == null)
{
container = null;
}
else
{
container = document.getElementById(containerID);
}
if(containerID == null || container != null)
{
if(container != null)
container.style.display = 'none';
if(alsoDisable)
disableValidators(containerID);
else
hideValidators(containerID);
}
}
//does the opposite of hide()
function show(alsoEnable, containerID)
{
if(alsoEnable == null)
alsoEnable = false;
var container;
if(containerID == null)
{
container = null;
}
else
{
container = document.getElementById(containerID);
}
if(containerID == null || container != null)
{
if(container != null)
container.style.display = 'block';
if(alsoEnable)
enableValidators(containerID);
else
showValidators(containerID);
}
}
//flips the state of the containerID control
function showHide(containerID)
{
var container;
if(containerID == null)
{
container = null;
}
else
{
container = document.getElementById(containerID);
}
if(containerID == null || container != null)
{
if(container.style.display == null)
{
hide(containerID);
}
else if(control.style.display == 'none')
{
show(containerID);
}
else
{
hide(containerID);
}
}
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
// END Show/Hide
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*/
使用方法也很簡單唷!
關閉驗證
disableValidators('控制項的ClientId');
開啟驗證
enableValidators('控制項的ClientId');
URL加密 (限定加密後的輸出,符合ASP.NET的ValidateRequest )
最主要是我這邊提出來的加密方式的輸出結果,可以符合ASP.NET的ValidateRequest的限制。
至於ValidateRequest的限制可以參考下面兩個網址。
http://www.microsoft.com/taiwan/msdn/library/2004/Mar-2004/ScriptingProtection.htm
http://www.microsoft.com/taiwan/msdn/library/2005/Mar-2005/securitybarriers.htm
Imports System.Text
Imports System.IO
Imports System.Security.Cryptography
Public Class Encrypt
Public Shared Function BAToHS(ByVal Datas As Byte()) As String
Dim str As String
Try
Dim str2 As String = ""
Dim str3 As String = ""
Dim num2 As Long = (vabytData.Length - 1)
Dim i As Long = 0
Do While (i <= num2)
str3 = Convert.ToByte(vabytData(CInt(i))).ToString("x")
If (str3.Length = 1) Then
str3 = ("0" & str3)
End If
str2 = (str2 & str3)
i = (i + 1)
Loop
str = str2
Catch exception1 As Exception
Throw
End Try
Return str
End Function
Public Shared Function BAToUS(ByVal vabytData As Byte()) As String
Dim str As String
Try
Dim encoding As New UnicodeEncoding
str = String.Concat(New String() {New String(encoding.GetChars(vabytData))})
Catch exception1 As Exception
Throw
End Try
Return str
End Function
Public Shared Function DESDecrypt(ByVal vstrEncryptedData As String, ByVal vabytKey As Byte(), ByVal vabytIV As Byte()) As String
Return Encrypt.BAToUS(Encrypt.DESDecrypt(Encrypt.HexStrToByteArray(vstrEncryptedData), vabytKey, vabytIV))
End Function
Public Shared Function DESDecrypt(ByVal vabytEncryptedData As Byte(), ByVal vabytKey As Byte(), ByVal vabytIV As Byte()) As Byte()
Dim stream2 As New MemoryStream
Dim provider As New DESCryptoServiceProvider
Dim stream As New CryptoStream(stream2, provider.CreateDecryptor(vabytKey, vabytIV), CryptoStreamMode.Write)
stream.Write(vabytEncryptedData, 0, vabytEncryptedData.Length)
stream.Close()
Return stream2.ToArray
End Function
Public Shared Function DESEncrypt(ByVal vabytSource As Byte(), ByVal vabytKey As Byte(), ByVal vabytIV As Byte()) As Byte()
Dim stream2 As New MemoryStream
Dim provider As New DESCryptoServiceProvider
Dim stream As New CryptoStream(stream2, provider.CreateEncryptor(vabytKey, vabytIV), CryptoStreamMode.Write)
stream.Write(vabytSource, 0, vabytSource.Length)
stream.Close()
Return stream2.ToArray
End Function
Public Shared Function DESEncrypt(ByVal vstrSource As String, ByVal vabytKey As Byte(), ByVal vabytIV As Byte()) As String
Return Encrypt.BAToHS(Encrypt.DESEncrypt(Encrypt.UniStrToByteArray(vstrSource), vabytKey, vabytIV))
End Function
Public Shared Function HSToBA(ByVal vstrData As String) As Byte()
Dim buffer As Byte()
Try
Dim num2 As Long = CLng(Math.Round(CDbl((CDbl(vstrData.Length) / 2))))
Dim buffer2 As Byte() = New Byte((CInt((num2 - 1)) + 1) - 1) {}
Dim num3 As Long = (num2 - 1)
Dim i As Long = 0
Do While (i <= num3)
Dim str As String = vstrData.Substring(CInt((i * 2)), 2)
buffer2(CInt(i)) = Convert.ToByte(str, &H10)
i = (i + 1)
Loop
buffer = buffer2
Catch exception1 As Exception
Throw
End Try
Return buffer
End Function
Public Shared Function USToBA(ByVal vstrFrom As String) As Byte()
Dim bytes As Byte()
Try
bytes = New UnicodeEncoding().GetBytes(vstrFrom)
Catch exception1 As Exception
Throw
End Try
Return bytes
End Function
End Class
上面這一段是編碼的Class,下面至一段是說明如何使用它
加密:
Encrypt.DESEncrypt("要編碼的文字", Encrypt.USToBA("KEY1"),Encrypt.USToBA("KEY2"))
解密:
Encrypt.DESDecrypt("要編碼的文字", Encrypt.USToBA("KEY1"),Encrypt.USToBA("KEY2"))
KEY1和KEY2是編碼時,對應的Key值,可以修改,但限定只能夠4碼,修改時記得要相對應!
以上這一些就是編碼的寫法跟用法了,至於如何套用到URL的編碼,各位可以依照自己的專案特性,來加以應用摟~~
另外還有一點就是各位比較關心的,就是用這樣的編碼出來的輸出結果到底有甚麼限制呢?
它編碼出來的規格是
輸出字元:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
每個字元的輸出位元:固定16碼(不管是中文或是英文)
Dynamic Add AsyncPostBackTrigger In UpdatePanel
遇到了一些棘手的問題,所以在這邊將它整理一下。
ASPX內的程式
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server"
UpdateMode="conditional">
<ContentTemplate>
.....
</ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="Panel1" runat="server">
</asp:Panel>
VB內的程式
Dim AjaxButton As New System.Web.UI.WebControls.Button
AjaxButton.ID = "XXX"
AjaxButton.Text = "XXX"
AjaxButton.UseSubmitBehavior = False '為了支援FireFox
AddHandler AjaxButton.Click, AddressOf Me.OnAjaxButton_Click
Me.UpdatePanel1.ContentTemplateContainer.Controls.Add(AjaxButton)
Dim trigger As New System.Web.UI.AsyncPostBackTrigger
trigger.ControlID = AjaxButton.ID
Me._UpdatePanelQ.Triggers.Add(trigger)
上面這段Code如果寫在Page Init中,那是沒有問題的,但是如果將它移到Page_Load中,就會有問題了,
它將可能造成非同步PostBack的Error,那此時就要另外加上下面的語法了。
先在外部宣告下面這一個Method
Private Shared triggerInitMethod As Reflection.MethodInfo = GetType(System.Web.UI.UpdatePanelTrigger).GetMethod("Initialize", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
這段Code緊接著在第一段Code的後面,去執行UpdatePanel的Initialize事件
If System.Web.UI.ScriptManager.GetCurrent(Me).IsInAsyncPostBack = True Then
triggerInitMethod.Invoke(trigger, Nothing)
End If
大功告成...
2007年11月12日
ViewState壓縮相容於UpdatePanel (VB.NET版本)
但是當我們將它應用於AJAX的專案時,我們發現了,使用UpdatePanel時,若有存取ViewState,則會造成取不到ViewState的窘境。
為此我們重新在Google上找尋了另外的版本加以改進。
下面這一段Code的ViewState壓縮將可以相容於UpdatePanel摟~~
(不過有一個缺點,就是壓縮效果比較差就是了...)
使用方法:直接將下面的Code複製至Page裡面,就可以了。不用任何的引用與觸發。
相關原理就不多做說明了,如果有網友想要知道其相關撰寫原理,再另外留言吧!我再進行整理發表。
'''
''' 壓縮
'''
'''
'''
'''
Private Function Compress(ByVal data() As Byte) As Byte()
Dim ms As New MemoryStream
Dim stream As New GZipStream(ms, CompressionMode.Compress)
stream.Write(data, 0, data.Length)
stream.Close()
Return ms.ToArray
End Function
'''
''' 解壓縮
'''
'''
'''
'''
Public Function Decompress(ByVal data() As Byte) As Byte()
Dim ms As New MemoryStream
ms.Write(data, 0, data.Length)
ms.Position = 0
Dim stream As New GZipStream(ms, CompressionMode.Decompress)
Dim temp As New MemoryStream
Dim buffer(1024) As Byte
While True
Dim read As Integer = stream.Read(buffer, 0, buffer.Length)
If read <= 0 Then
Exit While
Else
temp.Write(buffer, 0, read)
End If
End While
stream.Close()
Return temp.ToArray
End Function
Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal state As Object)
Dim pair As Pair
Dim persister As PageStatePersister = Me.PageStatePersister
Dim ViewState As Object
If TypeOf state Is Pair Then
pair = CType(state, Pair)
persister.ControlState = pair.First
ViewState = pair.Second
Else
ViewState = state
End If
Dim formatter As New LosFormatter
Dim writer As New StringWriter
formatter.Serialize(writer, ViewState)
Dim viewStateStr As String = writer.ToString()
Dim data As Byte() = Convert.FromBase64String(viewStateStr)
Dim compressedData As Byte() = Me.Compress(data)
Dim str As String = Convert.ToBase64String(compressedData)
persister.ViewState = str
persister.Save()
End Sub
Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
Dim persister As PageStatePersister = Me.PageStatePersister
persister.Load()
Dim viewState As String = persister.ViewState.ToString()
Dim data As Byte() = Convert.FromBase64String(viewState)
Dim uncompressedData As Byte() = Me.Decompress(data)
Dim str As String = Convert.ToBase64String(uncompressedData)
Dim formatter As New LosFormatter
Return New Pair(persister.ControlState, formatter.Deserialize(str))
End Function
清理磁碟 (清除系統垃圾檔案)
你知道當你使用你的作業系統一段時間後,系統上其實會生出一些莫名其妙的垃圾檔案嗎?
這些垃圾檔案可能是來自於瀏覽網頁的暫存檔,也可能是你使用了某一套軟體它所生出來的暫存檔。
這些對我們而言,它已經沒有繼續保存的必要了。所以下面就提供這一段code來讓你可以方便的去刪除你系統上一些不必要的檔案。
使用方法:
Step 1:新增一個純文字檔,並將其附檔名改為.bat
Step 2:將下面的code複製至該檔案內。
Step 3:點兩下執行它。
系統將會開始自動開始刪除檔案摟~~
是不是很簡單呢?
刪除完可能會多出許多的空間唷~~
試試看吧!~~
@echo off
echo 正在清除系統垃圾檔案中,請稍候......
del /f /s /q %systemdrive%\*.tmp
del /f /s /q %systemdrive%\*._mp
del /f /s /q %systemdrive%\*.log
del /f /s /q %systemdrive%\*.gid
del /f /s /q %systemdrive%\*.chk
del /f /s /q %systemdrive%\*.old
del /f /s /q %systemdrive%\recycled\*.*
del /f /s /q %windir%\*.bak
del /f /s /q %windir%\prefetch\*.*
rd /s /q %windir%\temp & md %windir%\temp
del /f /q %userprofile%\cookies\*.*
del /f /q %userprofile%\recent\*.*
del /f /s /q "%userprofile%\Local Settings\Temporary Internet Files\*.*"
del /f /s /q "%userprofile%\Local Settings\Temp\*.*"
del /f /s /q "%userprofile%\recent\*.*"
echo 清除系統垃圾檔案完成!!
echo. & pause
2007年11月11日
桂綸鎂
而在這一系列的國片中,一個人讓我的目標凝聚了過去...她就是『桂綸鎂』
對我而言他是一個新人,或許對其他人來說,它應該已經初到許久了...
它有一個不一樣的特質,讓人感動與歡笑的特質...這是一種說不出來的感覺...
它能夠將電影的氣氛傳達給我...
這一切的一切...所以我又開始看國片了...在此跟各位分享這一個有趣的電影人...
我想我說再多,也比不上你自己一點點的體會,所以我在這裡分享一些它的短片,讓大家慢慢的認識它~~
桂綸美跑去當OL了
Google Analyics
2007年11月10日
利用JavaScript驗證身分證字號是否正確(台灣)
Return True or False
//To Validate ID Number
function ValidateIDNumber(sId)
{
try
{
if(sId == "") return true;
sId = sId.toUpperCase();
if(sId.length != 10) return false;
var c1;
c1 = sId.charAt(0);
if(c1 < "A" || c1 > "Z") return false;
var str1;
str1 = sId.substring(1,10);
if(isNaN(str1)) return false;
var str2;
str2 = "ABCDEFGHJKLMNPQRSTUVWXYZIO";
var i1;
i1 = str2.indexOf(c1) + 10;
if(i1 < 10) return false;
sId = i1.toString() + str1
var intChkSum;
intChkSum = parseInt(sId.charAt(0)) + parseInt(sId.charAt(10));
for(var i=1;i<=9;i++)
{
intChkSum = intChkSum + parseInt(sId.charAt(i)) * (10 - i);
}
intChkSum = intChkSum % 10;
if(intChkSum!=0) return false;
}catch(e){
return false;
}
return true;
}
設定與取得options(ComboBox)的選取值(Select Value)
其實還有點麻煩,所以這邊就直接提供兩個Method來給各位使用,方便設定跟取得options的選項
function GetComboSelectedValue(objCombo)
{
return objCombo.options[objCombo.selectedIndex].value;
}
function SetComboSelectedValue(objCombo , strValue)
{
var i;
for(i=0;i<=objCombo.options.length -1; i++)
{
if(objCombo.options[i].value == strValue)
{
objCombo.options[i].selected = true;
return;
}else{
objCombo.options[i].selected = false;
}
}
}
利用JavaScript驗證統一編號是否正確(台灣)
這裡再補上一個JavaScript版本的。
//To Validate Tax ID
function ValidateTaxID(sTaxID)
{
try
{
var i;
var a1;
var a2;
var a3;
var a4;
var a5;
var b1;
var b2;
var b3;
var b4;
var b5;
var c1;
var c2;
var c3;
var c4;
var d1;
var d2;
var d3;
var d4;
var d5;
var d6;
var d7;
var cd8;
if(sTaxID.length != 8) return false;
var c;
for (i = 0; i < 8; i++)
{
c = sTaxID.charAt(i);
if ("0123456789".indexOf(c) == -1) return false;
}
d1 = parseInt(sTaxID.charAt(0));
d2 = parseInt(sTaxID.charAt(1));
d3 = parseInt(sTaxID.charAt(2));
d4 = parseInt(sTaxID.charAt(3));
d5 = parseInt(sTaxID.charAt(4));
d6 = parseInt(sTaxID.charAt(5));
d7 = parseInt(sTaxID.charAt(6));
cd8 = parseInt(sTaxID.charAt(7));
c1 = d1;
c2 = d3;
c3 = d5;
c4 = cd8;
a1 = parseInt((d2 * 2) / 10);
b1 = (d2 * 2) % 10;
a2 = parseInt((d4 * 2) / 10);
b2 = (d4 * 2) % 10;
a3 = parseInt((d6 * 2) / 10);
b3 = (d6 * 2) % 10;
a4 = parseInt((d7 * 4) / 10);
b4 = (d7 * 4) % 10;
a5 = parseInt((a4 + b4) / 10);
b5 = (a4 + b4) % 10;
if((a1 + b1 + c1 + a2 + b2 + c2 + a3 + b3 + c3 + a4 + b4 + c4) % 10 == 0) return true;
if(d7 = 7)
{
if((a1 + b1 + c1 + a2 + b2 + c2 + a3 + b3 + c3 + a5 + c4) % 10 == 0) return true;
}
return false;
}catch(e){
return false;
}
}
Runtime指定AP的Culture Info
而Culture一般而言都是直接在Web Config檔中設定,或是根據User的機器設定的語系來決定,
但是這樣做將無法讓使用者動態的去決定他要的語言,也就是多國語言無法進行線上的切換。
下面這段Code將是讓我們可以動態的去設定Culture Info,讓多國語言可以做線上的任意切換。
而Culture Info要自己想辦法記錄下來唷!不管是存在DB或是Cookie或是Session都可以...
Protected Overrides Sub InitializeCulture()
Me.UICulture = strCultureName
Me.Culture = strCultureName
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(strCultureName)
System.Threading.Thread.CurrentThread.CurrentUICulture = New System.Globalization.CultureInfo(strCultureName)
MyBase.InitializeCulture()
End Sub
strCultureName變數是你要去取得你自己控制的Culture Info
使用MasterPage後,FindControl找不到物件
但是到了.net 2.0之後,我們用了MasterPage,
然後發現竟然找不到Control了,怎麼會這樣呢?
原因是因為,他的Control容器架構改變了,
所以造成過去我們很習慣使用的Me.FindControl Method,將會很容易找不到我們要的元件...
因為你可能對於Control容器的架構不清楚...
而為了減輕Coding上的負擔,所以我在我的專案中,提供了兩個Method來替代過去的FindControl Method
'''
''' 找Page內的Control
'''
'''
'''
'''
Protected Function FindPageControl(ByVal strID As String) As System.Web.UI.Control
If Me.Master Is Nothing Then
Return Nothing
End If
'固定寫死找ContentPlaceHolder1的Control
Dim objContent As System.Web.UI.Control = Me.FindMasterControl(CMConst.ContentPlaceHolder_ID)
If objContent Is Nothing Then
Return Nothing
End If
Return objContent.FindControl(strID)
End Function
'''
''' 找MasterPage內的Control
'''
'''
'''
'''
Protected Function FindMasterControl(ByVal strID As String) As System.Web.UI.Control
If Me.Master Is Nothing Then
Return Nothing
End If
Return Me.Master.FindControl(strID)
End Function
在FindPageControl中,我固定寫死了ContentPlaceHolder1,因為在我們的專案中,我們只會用到一個ContentPlaceHolder,所以我們這樣做,而你可能可以改寫他的ContentPlaceHolder的ID,或是也將該ID做為參數的傳入值也是可以的。
有了這兩個Method,我們將可以很輕鬆的找到我們要的Control了。
2007年11月9日
ASP.NET 2.0 WebResource.axd and browser caching
<img
src="/SWS35/WebResource.axd?d=UoDB4h0Q5F6IGhlOeP9UpC...">
<script
src="/SWS35/WebResource.axd?d=KknCFrZBRSiOd8El3l1gbw2..."
type="text/javascript">
不用懷疑你直覺的想法,這兩個語法就是直接將圖片跟JavaScript檔案載入到Client端,
過去我們會直接在src的地方,用一個路徑+檔名的寫法,直接指名某一個檔案,
但是如果我們今天開發的是一個共用的Control呢?
每個專案所使用的路徑又不同,我們要將這一些檔案放在哪裡呢?過去我們可能會將它統一放置於\wwwroot\aspnet_client下面。
但是這樣的做法,造成我們在更新元件版本時,除了要更新dll以外,還要去更新aspnet_client下面的檔案,實在有點不方便。
所以在asp.net 2.0上就衍生出了WebResource的機制。
WebResource.axd他不是一個實體檔案,它只是一個虛擬的檔案而已。
因為他,所以我們可以很輕鬆的將一些Resource綁在DLL上面。(例如圖片、javascript file、css file...等。)
用法也很簡單,如下步驟:
Step 1:只要將該檔案加入Control的專案內,
Step 2:設定該檔案的"建置動作"屬性為"內嵌資源"
如下圖:

Step 3:在專案的\My Project\AssemblyInfo.vb檔中,加入下面程式碼
'定義WegResource
<Assembly:
System.Web.UI.WebResource("MyWebControls.CustomGridView.js",
"text/javascript", PerformSubstitution:=True)>
MyWebControls是你的Namespace(一般預設是你的專案名稱)
CustomGridView.js是你的檔案名稱。(包含附檔名)
Step 4:利用下面語法載入檔案
Me.Page.ClientScript.RegisterClientScriptResource(Me.GetType, "MyWebControls.CustomGridView.js")
這樣就可以輕鬆載入JS檔了
當然你也可以載入CSS、圖片...等。做法大同小異。只要在Step 4上面有所不同而已。
可以參考http://support.microsoft.com/kb/910442/zh-tw
另外有一點要注意的事情是,檔案的caching問題,
利用封包監測軟體去看,我們會發現,
以前我們直接指定檔名的時候,在browse沒有特殊設定的情況下,它的檔案只會在第一次瀏覽時才會下載,
但是用了WebResource之後,你會發現他怎麼每次postback都下載一次呢?
這樣不是很耗用網路頻寬嗎?
其實要去catch住他是很簡單的,
只要在Web Config檔中,將debug設定為false就可以了。
這樣的機制對於在開發的時候,是很有幫助的,不用怕JS檔案被catch住。但是在上線時就一定要更改為web config的debug屬性唷!
(雖然這是一般的資安規定都會要求的,但是還是很多人沒有這樣做。)
詳細大家可以參考下面網址
http://tech.blog.oceg.org/2006/06/aspnet-20-webresourceaxd-and-browser.html
將CSS由VS 2003搬到2005上無法完全套用
而最近剛好聽到一些朋友將過去在1.1上面的專案把它用2.0重新改寫,
而在般移CSS的這一部分,卻發生了很多的問題,因為他無法完全的在2.0上面呈現相同的效果。
例如"100%"這個數值,就有很大的變動,
很多人認為是.NET 2.0搞得鬼,或是IE7的問題,
其實並不是,我們仔細去看VS 2005為我們預設產生的html code,就可以略知一二了。
有一行宣告其結構定義的地方,
2003的版本:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2005的版本:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
有沒有發現,版本不一樣了!
那我們要怎麼讓過去的CSS可以完全的在新定義檔下呈現呢?
最簡單的解法就是將這一段替換回原本的2003版本,
但是這樣這做法我並不是很認同,因為這樣似乎有點在走回頭路的感覺,
因此我還是傾向於各個擊破,
body的高度只有內容物的高度,而不會是螢幕的高度,因為100%失效了,這會造成我們的畫面blocker失效。解法:將原本的body{...}給為html,body{...}就可以了!
類似的問題一定還很多,所以各位網友可以將你的問題提出來,大家可以在討論一下解法!
2007年11月3日
Show your live - Broadcast yourself
因為YouTube最近有了繁體中文版,所以又再度吸引了去努力瀏覽了它的網站,
而當我看了那麼多的Show出自己的短片之後,
讓我想起在數個月之前,曾經在某位學弟的Blog上面,看到了他送給他女朋友的生日短片
感覺還不錯,或許這就是YouTube原先的出發點吧!
希望大家可以透過它,來和朋友們,或是不認識的人,一同分享自己的生活,自己的幸福吧!
YouTube.com.tw
相信大多數的人都已經知道YouTube已經有繁體中文版了
正式的加上了.TW
相信對於使多熱愛YouTube的台灣網友而言,是一個相當大的好消息
因為你可以更方便去使用它了
下面這一段陳士駿簡短的談話內容中,主題環繞在【全球化,更需在地思考】
個人覺得相當有意思,也相當值得思考,因此特別將它轉載到Blog上來。
UN for Taiwan
利用VB.NET驗證統一編號是否正確(台灣)
'##SUMMARY 驗證統一編號是否正確
'
'##PARAM vstrTaxID 欲驗證的統一編號,例如 22425662
'
'##RETURNS 如果驗證結果正確則回傳 True,反之為 False。
'
'##REMARKS
'##REMARKS Example :
'##REMARKS
'##REMARKS Dim blnResult As Boolean = Validator.ValidateTaxID("22425662")
'
'##VERSIONS 0093/04/01 nick_shen New Create
Public Shared Function ValidateTaxID(ByVal vstrTaxID As String) As Boolean
Dim i As Integer
Dim a1 As Integer
Dim a2 As Integer
Dim a3 As Integer
Dim a4 As Integer
Dim a5 As Integer
Dim b1 As Integer
Dim b2 As Integer
Dim b3 As Integer
Dim b4 As Integer
Dim b5 As Integer
Dim c1 As Integer
Dim c2 As Integer
Dim c3 As Integer
Dim c4 As Integer
Dim d1 As Integer
Dim d2 As Integer
Dim d3 As Integer
Dim d4 As Integer
Dim d5 As Integer
Dim d6 As Integer
Dim d7 As Integer
Dim cd8 As Integer
'設定起始值
' ChkTaxID = False
'判斷長度
If Len(vstrTaxID) <> 8 Then
Return False
End If
'判斷字元
For i = 1 To 8
If InStr("0123456789", Mid(vstrTaxID, i, 1)) = 0 Then
Return False
End If
Next
'設定變數
d1 = CInt(Mid(vstrTaxID, 1, 1))
d2 = CInt(Mid(vstrTaxID, 2, 1))
d3 = CInt(Mid(vstrTaxID, 3, 1))
d4 = CInt(Mid(vstrTaxID, 4, 1))
d5 = CInt(Mid(vstrTaxID, 5, 1))
d6 = CInt(Mid(vstrTaxID, 6, 1))
d7 = CInt(Mid(vstrTaxID, 7, 1))
cd8 = CInt(Mid(vstrTaxID, 8, 1))
c1 = d1
c2 = d3
c3 = d5
c4 = cd8
a1 = Int((d2 * 2) / 10)
b1 = (d2 * 2) Mod 10
a2 = Int((d4 * 2) / 10)
b2 = (d4 * 2) Mod 10
a3 = Int((d6 * 2) / 10)
b3 = (d6 * 2) Mod 10
a4 = Int((d7 * 4) / 10)
b4 = (d7 * 4) Mod 10
a5 = Int((a4 + b4) / 10)
b5 = (a4 + b4) Mod 10
'計算公式
If (a1 + b1 + c1 + a2 + b2 + c2 + a3 + b3 + c3 + a4 + b4 + c4) Mod 10 = 0 Then
Return True
End If
If d7 = 7 Then
If (a1 + b1 + c1 + a2 + b2 + c2 + a3 + b3 + c3 + a5 + c4) Mod 10 = 0 Then
Return True
End If
End If
Return False
End Function
利用SQL驗證統一編號是否正確(台灣)
USE TTL_BPA_EAI
GO
IF EXISTS (SELECT * FROM sysobjects WHERE name = N'FN_CheckTaxID')
DROP FUNCTION FN_CheckTaxID
GO
CREATE FUNCTION FN_CheckTaxID
(
@TaxID NVARCHAR(50)
)RETURNS CHAR(1)
AS
BEGIN
--驗證統一編號是否正確
--@TaxID 欲驗證的統一編號
--如果驗證結果正確則回傳 '1' ELSE '0'
--2005/11/11 BRIAN
DECLARE @I INT
DECLARE @A1 INT
DECLARE @A2 INT
DECLARE @A3 INT
DECLARE @A4 INT
DECLARE @A5 INT
DECLARE @B1 INT
DECLARE @B2 INT
DECLARE @B3 INT
DECLARE @B4 INT
DECLARE @B5 INT
DECLARE @C1 INT
DECLARE @C2 INT
DECLARE @C3 INT
DECLARE @C4 INT
DECLARE @D1 INT
DECLARE @D2 INT
DECLARE @D3 INT
DECLARE @D4 INT
DECLARE @D5 INT
DECLARE @D6 INT
DECLARE @D7 INT
DECLARE @CD8 INT
--判斷長度
IF LEN(@TaxID) <> 8
RETURN '0'
--判斷字元
DECLARE @J INT
SET @J = 1
WHILE @J <= 8
BEGIN
IF CHARINDEX( SUBSTRING(@TaxID , @J , 1) , '0123456789') = 0
RETURN '0'
SET @J = @J + 1
END
--設定變數
SET @D1 = CAST(SUBSTRING(@TaxID , 1 , 1) AS INT)
SET @D2 = CAST(SUBSTRING(@TaxID , 2 , 1) AS INT)
SET @D3 = CAST(SUBSTRING(@TaxID , 3 , 1) AS INT)
SET @D4 = CAST(SUBSTRING(@TaxID , 4 , 1) AS INT)
SET @D5 = CAST(SUBSTRING(@TaxID , 5 , 1) AS INT)
SET @D6 = CAST(SUBSTRING(@TaxID , 6 , 1) AS INT)
SET @D7 = CAST(SUBSTRING(@TaxID , 7 , 1) AS INT)
SET @CD8 = CAST(SUBSTRING(@TaxID , 8 , 1) AS INT)
SET @C1 = @D1
SET @C2 = @D3
SET @C3 = @D5
SET @C4 = @CD8
SET @A1 = CAST(((@D2 * 2) / 10) AS INT )
SET @B1 = (@D2 * 2 ) % 10
SET @A2 = CAST(((@D4 * 2) / 10) AS INT )
SET @B2 = (@D4 * 2) % 10
SET @A3 = CAST(((@D6 * 2) / 10) AS INT )
SET @B3 = (@D6 * 2) % 10
SET @A4 = CAST(((@D7 * 4) / 10) AS INT )
SET @B4 = (@D7 * 4) % 10
SET @A5 = CAST(((@A4 + @B4) / 10) AS INT )
SET @B5 = (@A4 + @B4) % 10
--計算公式
IF (@A1 + @B1 + @C1 + @A2 + @B2 + @C2 + @A3 + @B3 + @C3 + @A4 + @B4 + @C4) % 10 = 0
RETURN '1'
IF @D7 = 7
BEGIN
IF (@A1 + @B1 + @C1 + @A2 + @B2 + @C2 + @A3 + @B3 + @C3 + @A5 + @C4 ) % 10 = 0
RETURN '1'
END
RETURN '0'
END
GO
-- =============================================
-- Example to execute function
-- =============================================
SELECT dbo.FN_CheckTaxID('01121111')
SELECT dbo.FN_CheckTaxID('22425662')
GO
利用SQL將某數值進行位數的補足
例如33.23
要變成033.230等
下面這個SQL就是要做這件事情。
IF EXISTS (SELECT * FROM sysobjects WHERE name = N'FN_FILL_TEXT')
DROP FUNCTION FN_FILL_TEXT
GO
CREATE FUNCTION FN_FILL_TEXT
(
@STR VARCHAR(20) , --要被處理的字串
@CON INT , --要顯示的位數(包含小數點)
@DEC INT , --小數位數
@REPLACE CHAR(1) --要被補上的字元
)RETURNS VARCHAR(50)
AS
BEGIN
RETURN REPLACE( STR(@STR , @CON , @DEC) , ' ' , @REPLACE )
END
GO
SELECT dbo.FN_FILL_TEXT('39.1','8','3','0')
GO
--結果:0039.100
SQL Null的排序問題
這邊就稍微講解一下,如何讓一個DB的欄位值為NULL時,
可以排到最後面去
SELECT CURR_DEADLINE,SUBMIT_TIME , STATUS , *
FROM SWS_REQUEST_M A
ORDER BY
CASE
WHEN CURR_DEADLINE IS NULL THEN 1
ELSE 0
END
,CURR_DEADLINE
在ORDER BY的地方,先利用CASE的方式,將要排序的欄位,做第一次的篩選,
將該欄位如果為NULL的話,設定為1,這樣它在ORDER BY的時候,就會排比較後面,
接下來第二個ORDER欄位才是你真正要排序的欄位,
這樣一來將可以將該欄為如果為NULL的,排到最後面,
剩下不是NULL的再根據內容來進行排序一次。
2007年11月2日
JavaScript Framework (jQuery)
做了一個簡單的介紹,說明為什麼我們要使用JavaScript Framework - jQuery的簡報。
在這邊將它做一些整理,希望對大家有幫助。

而當大部分的系統操作介面都開始朝向RIA前進時,我們能夠倖免嗎?
我想答案是肯定的吧!所以我們也免不了要開始開發出符合使用者期望的的操作介面來…
那使用者到底在想些什麼呢?他們的期望到底是什麼呢?
或許就是…

而為了滿足這些不斷擴展的使用者期望,一些新的技術或應用陸續的浮上檯面了…


而我們選擇了用AJAX和大量的JavaScript來滿足使用者的期望…
選擇它是因為我們覺得,以現有人員的技術背景來考量,
它的進入門檻比較低一點…因為它的code對我們而言比較熟悉也比較有親和力
但也因為我們選擇了這樣的搭配組合,所以我們也開始撰寫了大量的JavaScript,
當我們寫的越多,遇到的瓶頸與困難也越多…


遇到了這些問題,我們就在思考
…
其實網路上也有許多團體在發展JavaScript的Framework或Library…
那既然已經知道JavaScript也有Framework了,
那我們就開始思考,導入JavaScript的Framework是否有一些預設想要達到的目標或期望呢?
列出這一些將會有助於我們選擇一個比較適合我們的Framework.

1.最理想的狀況是,只要遵循library的語法來撰寫,就可以不用去理會跨browser的問題…
2.Reuse一些open source的程式,減少自行重新開發的程式
3.希望它可以使我們的程式更乾淨一些,可讀性更好一些
4.程式碼乾淨、可讀,相對的MA的負擔就會降低了
5.開發速度當然也是一個很重要的考量點
6.最後當然是學習成本不能太高摟~~總不能為了要達到這些目的,我們要額外花上一兩個月來學習如何使用它吧!這樣可能不是很符合經濟效益。

那到底要用哪一家的Library其實還蠻困擾我們的,
目前網路上有許多有名的JavaScript的Library,各自有各自的愛好者,而我最後是選擇了用jQuery來做我們的基底。
那為什麼要選用jQuery呢?或許是被它的slogan write less , do more所吸引了吧!

這麼多的library其實我們也沒有每一個library都去看過、比較過,我們主要去看過prototype和jQuery而已,主要是因為時間上的考量,而且這兩個library是在網路上最常被拿來比較的。
那在這兩個library當中,我個人是覺的jQuery的code是比較簡潔的,也跟我過去學的程式語言的style比較相近一些。(這一點java派的人可能會反駁我,因為有人聲稱prototype比較像java,而jQuery比較像ruby。)
很小,所以對於網路傳輸的負擔很輕。因為JavaScript是必須要將全部的code傳到Client去執行的,所以我們不太可能去選擇一個很強但是又很大的Framework,要不然這樣對於網路的傳輸負擔其實是蠻大的。
jQuery算是相當熱門的JavaScript的Framework,因為熱門,所以自然就有很多愛好者願意投入來開發它,自然的資源就會比較多。而且他也是最近一兩年新崛起的熱門資源,而且還發展的蠻茁壯的,所以應該沒有那麼快被淘汰吧?
另外jQuery算是我比較早接觸的JavaScript library可能有些先入為主的觀念,所以還是比較喜歡用它…

這一個畫面是從jQuery的官方網站首頁上擷取下來的,它對於jQuery的解釋。
他說jQuery是一快速、簡明的javascript library,可以幫我們簡化HTML還有AJAX的處理。
它是設計來改變我們對於javascript的寫法的。
然後他這邊也聲稱用jQuery寫出來10行code的功能,在一般的JavaScript上面,可能要用20行才可以完成。
然後他這邊也強調,你如果要把這10行code往下精簡到2~3行是不太可能的。
這也就告訴我們,其實用jQuery寫出來的javascript已經是很精簡的code了。
但是他這邊又補上了一句,對於jQuery code的評價是:『Quick and Dirty』

這個畫面也是jQuery的官方網站首頁上copy下來的,
它有提到他們的library支援IE6.0以上還有FireFox1.5以上甚至還有其他的browser。
所以對我們而言他已經能夠幫助我們解決跨browser的問題了。
那從這些簡單的jQuery介紹,
除了學習成本以外,它似乎都已經滿足我們剛剛提出對於Framework的期望了。
那這些都只是紙上談兵,那接下來我們可以稍微看一下他的語法,來了解一下他的威力到底在哪邊…

jQuery的Selector它是一個很強大的功能,
它可以幫助我們很快速的去尋找到頁面上任何我們想要的物件
另外他可以搭配Xpath來找尋物件,所以對於Xpath和CSS越熟的人,來使用jQuery應該越能夠得心應手。

1.取代過去的dcoument.getElementById
2.取代過去的document.getElementByTagName
兩個的差別在於一個在Id前面有#字號,一個沒有…
後面這3個語法如果用一般的javascript語法來寫的話,我們可能都需要用一個for迴圈去跑它,
然後再個別去判斷它的屬性,再來指定他的相關Value
由這幾個簡單的語法來看,會發覺,光是打字就可以省下蠻多的了,程式碼也會比較簡潔一些。

那接下來我們就先來看一個簡單的範例,來讓大家體驗一下jQuery的威力
現在有一個需求,就是將所有a tag的連結物件,且id為e_links的控制項,當點選連結時,先詢問他是否執行。
那以一般的JS語法,大致上是這樣寫的

那我們現在利用jQuery的語法來改寫一下,你發現它的程式碼是不是簡潔多了?


我們現在撰寫JavaScript有很大的一部分是用來撰寫AJAX的相關處理的,
所以jQuery對於AJAX的相關支援也是很重要的,所以我們來看一下它提供了我們甚麼東西
1. 這個語法是將某一個HTML內容,load到某一個物件內。
2. 他是沒有回傳值給client端的
第一個參數是要執行的程式網址或是名稱
第二個參數是傳入要傳給該隻程式的參數,上面必須要指定型態,並且利用hash的方式來傳送
第三個參數是執行後要執行的javascript的function。
第二個參數跟第三個參數都是可以不用傳的。

除了基本的AJAX處理之外,也有提供比較詳細處理的AJAX Method
在這邊我們可以指定AJAX的time out時間,
傳輸的格式、
失敗要執行的function
成功時要執行的function

Post那個函數在我們的專案中,用的還蠻多的,像是利用它來做多國語言版的alert method
因為多國語言的訊息檔是在Server端,所以我們是利用AJAX的方法到Server端去取得Message後alert
像這樣的功能應用,如果用過去的XML HTTP Request來做的話,可能需要程式碼就會多很多。

另外jQuery也可以幫我們的HTML添加一些動畫效果,
例如這個範例是影藏某一個控制項,我們可以在他後面加入屬性去控制的隱藏和顯示的速度
做出來的效果就好像powerpoint的動畫一樣,會有漸層的效果。
隱藏有,當然也有顯示的了。

其實jQuery的UI還做了很多其他的功能,他都是額外採用plugin的方式附加進來的
這個網站是jQuery UI的官方網站,因為我們專案中目前還沒有大量使用它,那就不多做詳細介紹了。


對於jQuery的使用,我們用的還蠻測底的,
連一些自己包的Control為了要讓他可以跨Browser,也用了它,
所以我們發現其他專案要來Reuse我們的東西時,也需要一併include jQuery
目前遇到的專案看起來還好,因為它們原本沒有用任何的javascript framework
所以只要把我們用的jQuery include進來就可了,
但是如果別的專案已經有使用了其他的framework的話,可能就需要做一些調整了才能使用了。





