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,是不是值得,就請大家自己判斷了。

2009年6月29日

FDB選擇browser的問題

最近恢復使用fdb來debug swf檔案。但在我的機器上遇到一個麻煩的問題,就是每次都用safari打開debug player,偏偏safari在我的機器上跑得並不順。經過了一些搜尋,找到這一篇:

http://www.jetbrains.net/jira/browse/IDEADEV-34701

處理了一下,很快就能用firefox。但是遇到了一些不明的問題,幾乎不能設定breakpoint。ie就沒有這個問題,我想,單純只是因為ActiveX的架構...

2008年7月19日

Set Nocount

好吧,我只能說我對adodb生疏太久了,這樣的一個bug居然要快一個星期才找到...

事情是這樣的,我要做一份report,根據年月分,所以我寫了一段這樣的SQL


create procedure get_message_count_by_user
@ctrlId nvarchar(32),
@sdate datetime,
@edate datetime
as

declare @sd datetime, @ed datetime
create table #temp (sd datetime, ed datetime , ctTotal int, ctR int, ctS int, ctnp int)
insert #temp select sdate, edate, 0, 0, 0, 0 from sep_month(@sdate, @edate)
update #temp set ctTotal=t1
from (select sd, count(sid) t1 from #temp as s, messageboard
where contentdate>=s.sd and s.ed>contentdate and groupno=@ctrlId and deleteUser is null and
(status='2' or isnull(returnUser,'')<>@ctrlId )
group by sd ) as a
where #temp.sd=a.sd
update #temp set ctR=t1
from (select sd, count(sid) t1 from #temp as s, messageboard
where contentdate>=s.sd and contentdate<s.ed and groupno=@ctrlId and deleteUser is null and
status='2'
group by sd ) as a
where #temp.sd=a.sd
update #temp set ctS=t1
from (select sd, count(sid) t1 from #temp as s, messageboard
where contentdate>=s.sd and contentdate<s.ed and groupno=@ctrlId and deleteUser is null and
status='5'
group by sd ) as a
where #temp.sd=a.sd
update #temp set ctNP=ctTotal-ctR-ctS

select * from #temp


呼叫這個stored procedure,在asp.net一點問題也沒有,但是在asp中,我就是沒有辦法叫adodb取得#temp中的資料。測試了很久,甚至把stored procedure一行一行拆開來測試,結果發現:Insert #temp select 這一行一加入之後,後面的select敘述就沒有辦法傳回值了。這使得我想起很久很久以前(應該是七年前)我也遇過一個類似的問題,於是把資料庫一個一個找出來,在眾多的stored procedure中搜尋,終於看到一個熟悉的字眼:set nocount。於是在開頭(第六行)跟select * from #temp之前(第29行)分別加上:set nocount on, set nocount off,問題就解決了。

不過說到set nocount,這讓我想起許多陳年往事,還牽涉到一位如今是M$名嘴級的講師。這是個又臭又長的故事,有機會再說。

2008年6月11日

iPhone 2.0 的遠見

在 iPhone 2.0 上市之前,聽到一個之前專寫c#的朋友說,他最近買了一部mac在學習寫iPhone程式,這讓我驚訝了好一會兒。但看完了WWDC 2008 Keynote,我知道他的選擇是有意義的。

所有人看完 Keynote 的時候,注意到的都是199元。我看到的,卻是 "iPhone is the phone that changes the phones forever."

steve jobs 在1984年推出Macintosh的時候,動機就是:我要一部可以改變世界的電腦。Macintosh的確改變了整個電腦世界,唯一的問題只是:從中獲利的不是Apple,而是M$。1997年回鍋的steve,雖然透過iMac創造了話題,但是卻沒有什麼機會再度改變世界。一直到iPod,不,正確的說,是iTunes,改變了音樂販售的世界,也就改變了製作音樂這個行業。

iPod的發跡,除了金錢上的回報之外,有沒有為他們自己留下什麼可怕的武器?有,答案就是iTunes,以及操作iTunes上得到的學習。仔細想想,iTunes是世界上,唯一針對一個單一硬體商品進行加值販售的網路通路,這讓很多其他人起而仿效。我認為:iTunes是一把刀,真正的重點是:當你有了一把刀,可以直接切進你的消費群,你會想拿來幹嘛?

2008年5月28日

Safari的強勢推廣

Safari目前市占率約為5%,而蘋果公司3月開始透過iTunes的自動更新大力推廣Safari。這種強勢推廣已有一些效果,根據Net Applications統計,Safari在視窗電腦的市占率3月時成長200%。

這邊的關鍵字是:強勢推廣。嗯,強勢推廣...