2011年5月9日

在.aspx中直接呼叫System.Diagnostics.Trace.WriteLine不會有作用

這個問題之前遇到過,被以前的外包解決過。這次自己遇到,卻一直沒想起來有這件事情,所以把原來的連結貼一遍:

http://www.alexthissen.nl/blogs/main/archive/2007/02/11/viewing-diagnostics-trace-info-in-an-asp-net-website.aspx

簡單講:asp.net會把我們的.aspx轉換成.cs(或.vb)。然後再呼叫csc把產生的程式碼編譯完成。後面這道編譯的手續,如果沒有把/d:Trace打開,產生的程式碼就會忽略System.Diagnostics.Trace。這篇教的就是怎麼把這個選項打開。

2011年5月6日

「Viewstate MAC 的驗證失敗」 的另一個可能

「Viewstate MAC 的驗證失敗。blah blah blah machineKey 設定 blah blah」錯誤,是一個常見的 asp.net webform 問題(好累,以後都要說是 MVC 還是 webform )。起因多半來自兩個:

1. 是 webfarm 的設定,就是向A主機要了xxx.aspx,但postback卻到了B主機。實務上,我們還是寧可用big IP這類的產品做分流,遠比用軟體手段設定session state mirror問題要少。這個部分多半要找網管確認問題,比較麻煩。

2. 是讓頁面自動做postback,但卻在Viewstate還沒load完前就進行。

以上的內容,這裡有比較詳細的解釋

昨天客戶的客戶又發生這樣的錯誤,原來以為是 1.,但客戶說他自己之前偶而也會遇到。這個「偶而」讓我覺得很奇怪,因為公司內部是不會透過Big IP的。把 asp.net 2.0 關於 machinekey 的 security 章節讀完了以後,才想到:阿,Autogenerate 的 machineKey也會是問題阿!

Google了一下,果然:
http://social.msdn.microsoft.com/Forums/en-US/netfxsetup/thread/1a3a947b-fda0-4446-a4c7-7e8730d4064d/

上面討論串的回答有提到這一點,也就是每次app pool 被recycle以後,machineKey就會重新產生一次。如果使用者之前就進入我們的網站,但卻很久沒有進行任何操作,等到 app pool 被 recycle了以後,使用者卻用recycle之前的網頁進行postback,就會導致這樣的情況發生。

所以比較安全的作法,就還是把machineKey給定下來。

2011年5月3日

JQuery Timer

老實說,我並不是很常寫複雜的javascript。最近手癢把一個原來要用flash完成的自動換圖,改用javascript寫。由於對 setInterval 深惡痛覺,就找了半天看有沒有Timer可用。找了半天,發現大部分的都用callback,也有closure的問題,再找下去也不是辦法,就決定自己寫一個。

function Timer(delay, repeatCount) {
this.delay = delay;
this.repeatCount = repeatCount;
this.currentCount = 0;
this.timeHandle = 0;
this.running = false;
this.start = function() {
this.timeHandle = setInterval(Timer.delegate(this, this._timer), this.delay);
running = true;
}
this.reset = function() {
this.stop();
this.currentCount = 0;
}
this.stop = function() {
if (this.timeHandle != 0) {
clearInterval(this.timeHandle);
this.timeHandle = 0;
}
this.running = false;
}
this._timer = function() {
$(this).trigger($.Event("timer"));
if (this.repeatCount > 0) {
this.currentCount++;
if (this.currentCount >= this.repeatCount) {
this.reset();
}
}
}
}
Timer.delegate = function(obj, func) {
var f = function() {
var target = arguments.callee.target;
var func = arguments.callee.func;
return func.apply(target, arguments);
};
f.target = obj;
f.func = func;
return f;
}

使用的方式:需要先載入jquery(只是要一個能 trigger event 的 framework)。用 bind("timer", handler) 去接收timer事件。

var ct = 0;
function timer_tick(event) {
ct++;
alert(ct + "," + this.currentCount);
}

var timer = new Timer(5000, 3);
$(timer).bind("timer", timer_tick);
timer.start();

這個是照著flash.utils.Timer刻的,用法也幾乎相同(用javascript模仿read-only,實在太囉唆了,所以沒做),不熟悉的人可以去 http://help.adobe.com/zh_TW/AS3LCR/Flash_10.0/flash/utils/Timer.html 看。至於這麼一點功能卻要 load 一個龐大的 jquery,是不是值得,就請大家自己判斷了。