金玉良言 - 沉思錄:精華語錄(超越自己)

  • 如果我錯了,我將愉快地改變自己。 
  • 自己是自己最大的敵人。 
  • 每個人都是舞台上的主角。 
  • 能戰勝自我的人,才是真正的強者。 
  • 人生的自由,在於把苦變成「樂」。 
  • 愉接受不可控制的事物。 
  • 不要渴求我們無法控制的東西。 
  • 人的真正強大,來自於內心的強大。
很多東西,寫的再美,你有去走過,你還是不會懂的。我很感念及想念在經營事業的那一段日子。讓我懂了很多東西,讓我知道什麼是感動、感情、感念。能看的懂文字背後的文字。

Tool - 全球國家列表

同事跟我要「全球國家」的資料,剛好有整理過這方面的資料,應該其他人也會有這方面的需求,就分享給大家,此資料參考 http://en.wikipedia.org/wiki/ISO_3166-1 製作。

全球國家列表(含2簡碼,3簡碼,3數字碼)
CountryId Name Alpha2 Alpha3 Numeric3
1 Afghanistan AF AFG 004
2 Åland Islands AX ALA 248
3 Albania AL ALB 008
4 Algeria DZ DZA 012
5 American Samoa AS ASM 016
6 Andorra AD AND 020
7 Angola AO AGO 024
8 Anguilla AI AIA 660
9 Antarctica AQ ATA 010
10 Antigua and Barbuda AG ATG 028
11 Argentina AR ARG 032
12 Armenia AM ARM 051
13 Aruba AW ABW 533
14 Australia AU AUS 036
15 Austria AT AUT 040
16 Azerbaijan AZ AZE 031
17 Bahamas BS BHS 044
18 Bahrain BH BHR 048
19 Bangladesh BD BGD 050
20 Barbados BB BRB 052
21 Belarus BY BLR 112
22 Belgium BE BEL 056
23 Belize BZ BLZ 084
24 Benin BJ BEN 204
25 Bermuda BM BMU 060
26 Bhutan BT BTN 064
27 Bolivia, Plurinational State of BO BOL 068
28 Bonaire, Saint Eustatius and Saba BQ BES 535
29 Bosnia and Herzegovina BA BIH 070
30 Botswana BW BWA 072
31 Bouvet Island BV BVT 074
32 Brazil BR BRA 076
33 British Indian Ocean Territory IO IOT 086
34 Brunei Darussalam BN BRN 096
35 Bulgaria BG BGR 100
36 Burkina Faso BF BFA 854
37 Burundi BI BDI 108
38 Cambodia KH KHM 116
39 Cameroon CM CMR 120
40 Canada CA CAN 124
41 Cape Verde CV CPV 132
42 Cayman Islands KY CYM 136
43 Central African Republic CF CAF 140
44 Chad TD TCD 148
45 Chile CL CHL 152
46 China CN CHN 156
47 Christmas Island CX CXR 162
48 Cocos (Keeling) Islands CC CCK 166
49 Colombia CO COL 170
50 Comoros KM COM 174
51 Congo CG COG 178
52 Congo, the Democratic Republic of the CD COD 180
53 Cook Islands CK COK 184
54 Costa Rica CR CRI 188
55 Côte d'Ivoire CI CIV 384
56 Croatia HR HRV 191
57 Cuba CU CUB 192
58 Curaçao CW CUW 531
59 Cyprus CY CYP 196
60 Czech Republic CZ CZE 203
61 Denmark DK DNK 208
62 Djibouti DJ DJI 262
63 Dominica DM DMA 212
64 Dominican Republic DO DOM 214
65 Ecuador EC ECU 218
66 Egypt EG EGY 818
67 El Salvador SV SLV 222
68 Equatorial Guinea GQ GNQ 226
69 Eritrea ER ERI 232
70 Estonia EE EST 233
71 Ethiopia ET ETH 231
72 Falkland Islands (Malvinas) FK FLK 238
73 Faroe Islands FO FRO 234
74 Fiji FJ FJI 242
75 Finland FI FIN 246
76 France FR FRA 250
77 French Guiana GF GUF 254
78 French Polynesia PF PYF 258
79 French Southern Territories TF ATF 260
80 Gabon GA GAB 266
81 Gambia GM GMB 270
82 Georgia GE GEO 268
83 Germany DE DEU 276
84 Ghana GH GHA 288
85 Gibraltar GI GIB 292
86 Greece GR GRC 300
87 Greenland GL GRL 304
88 Grenada GD GRD 308
89 Guadeloupe GP GLP 312
90 Guam GU GUM 316
91 Guatemala GT GTM 320
92 Guernsey GG GGY 831
93 Guinea GN GIN 324
94 Guinea-Bissau GW GNB 624
95 Guyana GY GUY 328
96 Haiti HT HTI 332
97 Heard Island and McDonald Islands HM HMD 334
98 Holy See (Vatican City State) VA VAT 336
99 Honduras HN HND 340
100 Hong Kong HK HKG 344
101 Hungary HU HUN 348
102 Iceland IS ISL 352
103 India IN IND 356
104 Indonesia ID IDN 360
105 Iran, Islamic Republic of IR IRN 364
106 Iraq IQ IRQ 368
107 Ireland IE IRL 372
108 Isle of Man IM IMN 833
109 Israel IL ISR 376
110 Italy IT ITA 380
111 Jamaica JM JAM 388
112 Japan JP JPN 392
113 Jersey JE JEY 832
114 Jordan JO JOR 400
115 Kazakhstan KZ KAZ 398
116 Kenya KE KEN 404
117 Kiribati KI KIR 296
118 Korea, Democratic People's Republic of KP PRK 408
119 Korea, Republic of KR KOR 410
120 Kuwait KW KWT 414
121 Kyrgyzstan KG KGZ 417
122 Lao People's Democratic Republic LA LAO 418
123 Latvia LV LVA 428
124 Lebanon LB LBN 422
125 Lesotho LS LSO 426
126 Liberia LR LBR 430
127 Libyan Arab Jamahiriya LY LBY 434
128 Liechtenstein LI LIE 438
129 Lithuania LT LTU 440
130 Luxembourg LU LUX 442
131 Macao MO MAC 446
132 Macedonia, the former Yugoslav Republic of MK MKD 807
133 Madagascar MG MDG 450
134 Malawi MW MWI 454
135 Malaysia MY MYS 458
136 Maldives MV MDV 462
137 Mali ML MLI 466
138 Malta MT MLT 470
139 Marshall Islands MH MHL 584
140 Martinique MQ MTQ 474
141 Mauritania MR MRT 478
142 Mauritius MU MUS 480
143 Mayotte YT MYT 175
144 Mexico MX MEX 484
145 Micronesia, Federated States of FM FSM 583
146 Moldova, Republic of MD MDA 498
147 Monaco MC MCO 492
148 Mongolia MN MNG 496
149 Montenegro ME MNE 499
150 Montserrat MS MSR 500
151 Morocco MA MAR 504
152 Mozambique MZ MOZ 508
153 Myanmar MM MMR 104
154 Namibia NA NAM 516
155 Nauru NR NRU 520
156 Nepal NP NPL 524
157 Netherlands NL NLD 528
158 New Caledonia NC NCL 540
159 New Zealand NZ NZL 554
160 Nicaragua NI NIC 558
161 Niger NE NER 562
162 Nigeria NG NGA 566
163 Niue NU NIU 570
164 Norfolk Island NF NFK 574
165 Northern Mariana Islands MP MNP 580
166 Norway NO NOR 578
167 Oman OM OMN 512
168 Pakistan PK PAK 586
169 Palau PW PLW 585
170 Palestinian Territory, Occupied PS PSE 275
171 Panama PA PAN 591
172 Papua New Guinea PG PNG 598
173 Paraguay PY PRY 600
174 Peru PE PER 604
175 Philippines PH PHL 608
176 Pitcairn PN PCN 612
177 Poland PL POL 616
178 Portugal PT PRT 620
179 Puerto Rico PR PRI 630
180 Qatar QA QAT 634
181 Réunion RE REU 638
182 Romania RO ROU 642
183 Russian Federation RU RUS 643
184 Rwanda RW RWA 646
185 Saint Barthélemy BL BLM 652
186 Saint Helena, Ascension and Tristan da Cunha SH SHN 654
187 Saint Kitts and Nevis KN KNA 659
188 Saint Lucia LC LCA 662
189 Saint Martin (French part) MF MAF 663
190 Saint Pierre and Miquelon PM SPM 666
191 Saint Vincent and the Grenadines VC VCT 670
192 Samoa WS WSM 882
193 San Marino SM SMR 674
194 Sao Tome and Principe ST STP 678
195 Saudi Arabia SA SAU 682
196 Senegal SN SEN 686
197 Serbia RS SRB 688
198 Seychelles SC SYC 690
199 Sierra Leone SL SLE 694
200 Singapore SG SGP 702
201 Sint Maarten (Dutch part) SX SXM 534
202 Slovakia SK SVK 703
203 Slovenia SI SVN 705
204 Solomon Islands SB SLB 090
205 Somalia SO SOM 706
206 South Africa ZA ZAF 710
207 South Georgia and the South Sandwich Islands GS SGS 239
208 Spain ES ESP 724
209 Sri Lanka LK LKA 144
210 Sudan SD SDN 736
211 Suriname SR SUR 740
212 Svalbard and Jan Mayen SJ SJM 744
213 Swaziland SZ SWZ 748
214 Sweden SE SWE 752
215 Switzerland CH CHE 756
216 Syrian Arab Republic SY SYR 760
217 Taiwan, Province of China TW TWN 158
218 Tajikistan TJ TJK 762
219 Tanzania, United Republic of TZ TZA 834
220 Thailand TH THA 764
221 Timor-Leste TL TLS 626
222 Togo TG TGO 768
223 Tokelau TK TKL 772
224 Tonga TO TON 776
225 Trinidad and Tobago TT TTO 780
226 Tunisia TN TUN 788
227 Turkey TR TUR 792
228 Turkmenistan TM TKM 795
229 Turks and Caicos Islands TC TCA 796
230 Tuvalu TV TUV 798
231 Uganda UG UGA 800
232 Ukraine UA UKR 804
233 United Arab Emirates AE ARE 784
234 United Kingdom GB GBR 826
235 United States US USA 840
236 United States Minor Outlying Islands UM UMI 581
237 Uruguay UY URY 858
238 Uzbekistan UZ UZB 860
239 Vanuatu VU VUT 548
240 Venezuela, Bolivarian Republic of VE VEN 862
241 Viet Nam VN VNM 704
242 Virgin Islands, British VG VGB 092
243 Virgin Islands, U.S. VI VIR 850
244 Wallis and Futuna WF WLF 876
245 Western Sahara EH ESH 732
246 Yemen YE YEM 887
247 Zambia ZM ZMB 894
248 Zimbabwe ZW ZWE 716

另外我也幫各位準備好Excel檔:


內含 Excel 2003, Excel 2007 兩個格式的檔案,方便各方直接「匯入」資料庫使用。有需要者,請自行取用。

參考:

Tool - 讓你知道什麼是極致壓縮的7-Zip

昨天我介紹了「Visual Studio 2010 and .NET Framework 4 教學資源包」,因為它本身是個「自解縮壓檔」,只是進行解壓縮,透過資料夾內的Default.htm來連結各位網頁使用,它本身不是 Application。

所以我就想把原始下載回來的 VS2010TrainingKitJune2011.Setup.exe 直接 Copy 隨身碟中,帶回家,然後複製一份到電腦中,If 金剛帶小孩有時間 then 就看看此教學資源包。畢竟下載回來要 421 MB,家中網路又沒公司快,重複下載又浪費我的時間。

不過這時興起我的一個念頭,這份 Visual Studio 2010 and .NET Framework 4 Training Kit 解壓縮完的大小是 1.76 GB,如果我使用「號稱」超強的壓縮軟體 7-ZIP 來壓縮這份文件,會是什麼結果呢?

我很好奇,所以我們使用 7-ZIP 裡的極致壓縮來壓縮這 1.76 GB 的 Training Kit 目錄,也借此介紹此一免費又強大的壓縮/解壓縮工具,另外,我也與市面上另兩套 WinRAR, WinZIP 做了比較。

Visual Studio 2010 and .NET Framework 4 教學資源包

快點來下載「Visual Studio 2010 and .NET Framework 4 教學資源包原廠出品,品質保證,而且所含內容不只如標頭,只含 Visual Studio 2010, .NET Framework 4而已。整個 Visual Studio 2010 and .NET Framework 4 教學資源包內含有的主題有:

  • C# 4
  • Visual Basic 10
  • F#
  • Parallel Extensions
  • Windows Communication Foundation
  • Windows Workflow
  • Windows Presentation Foundation
  • Silverlight 4
  • ASP.NET 4
  • Windows 7
  • Entity Framework
  • ADO.NET Data Services
  • Managed Extensibility Framework
  • Application Lifecycle Management
  • Windows Azure
怎麼樣,夠你看了吧!

育嬰假- (4) 一個完整的家

太太的責任

愛心、慈心、悲心是女性的優點,如何引導先生做好事、走好路,是做太太的責任。《靜思語 第二集 36頁》
首先,要感謝我太太,成為情人、成為夫妻、成為人妻,一路上就像證嚴法師的話。為了「家」她可以做一切的事,包括跑去擺地攤。她的偉大,我無法形容,我對她,已經不知道什麼是愛?因為愛只是一個字。 

她為了二個寶貝為了這個家,請了一年的育嬰假,這一年有許多讓我改觀的事。

什麼是家?

從來沒想過,反正就是結婚,住在一起,就叫家吧。是嗎?
買個房子,買個傢俱,早上出門上班,晚上回來,然後睡在同一張床上,就叫家吧。是嗎?

從來沒想過這個問題:「什麼是家?」還好有這一年的育嬰假,讓我知道什麼是家。

結婚前,我們已經是兩個「上班族」,結婚後,更是兩個「上班族」,有了兩個寶貝後,想那麼多,賺錢要緊,管他什麼族。單身前(沒生小孩),時間自己的,錢自己的,什麼都是自己的。但打怪升級後,時間~寶貝們的,錢~寶貝們的,什麼都是寶貝的。

育嬰假之前,兩人上班,從來沒有感到什麼不對勁。育嬰假之後,我才我知道,家裡有一個人的差異有多大。上班,反正就是出門,送小孩去保母那裡,然後我看一天的Monitor,打一天的Keyboard,婆婆整一天的小朋友。然後下班,接寶貝回家,玩一下,然後送她們上床,週而復始。

育嬰假讓我們的生活有了意義。

早上有熱熱的早餐可以吃,中午有滿滿愛心的便當可以吃,晚上有滿滿一桌菜湯,讓你每天吃到快吐,還是一直吃。

早上有大寶與二寶的十八相送,又是抱又是親,晚上回來,又是大寶與二寶的大聲尖叫,然後衝過要你抱抱。尤其是二寶,連放個包包,脫個鞋的時間都沒有,不然就放聲大哭。

每天,我都準時下班,不準時下班,我會死,我太想她們,我太想家。

上班,帶小花散聊天的話題都是公事、八掛…,聽久了,都智障了。育嬰假,每天聊天的都二位寶貝每天的成長,今天大寶做了什麼天兵的事,說了什麼天兵的話;二寶怎麼跟阿花玩,玩一玩拔阿花的毛…,真的,很多時候我都笑到嘴都酸了,還在笑。

最美好的時光

終於知道,為什麼早期的社會要男主外、女主內。以前總覺得雙薪沒什麼不好,現在很後悔,沒有得到那個能力,可以讓婆婆當一個人全職媽媽。在育嬰假結束之前一~二個月,婆婆心情低落,原因只是簡單的不能再陪小孩,而且時間越近,心情趣糟。小孩也沒陪好,家也沒顧好。那段時間,看在我眼,痛在我心。

第一個大寶貝時,一開始就給保母帶。第二個寶貝時,婆婆決定自己帶時,剛開始還有點擔心,能不能當個好媽媽,後來發現,想太多,帶孩子太好玩了。也因為大寶貝一開始就是白天給保母帶,晚上我們帶回家,其實沒有太多時間陪伴,就要送大寶貝上床睡覺了,對她的一切,都只能來自那每天晚上接送的幾分鐘,忙時,也是只能透過那連絡本上短短幾句話來了解。

其實,那時候對於這樣,我們已經很滿足了。

我們的育嬰假是,妹妹0 ~ 1歲,姐姐是1.5 ~ 2.5歲,這一年來,我們完完整整的陪伴、相處、了解孩子,原來我們失去的不是錢。有了育嬰假後,我們才知道,我們真的是好可憐 ( 哭ing... ),我們把寶貝們最美好的時光送給別人,然後還要拿錢給人家。

育嬰飯菜

現在,那接送的幾分鐘,連絡本的的幾句話,已經無法滿足我們,我恨,我恨我自己。我感謝,感謝我們的父母親,我與婆婆都是在宜蘭這好山好水的地方長大,我們都是在大家族裡成長,與現在的小家庭是個很大的對比。

社會一直改變,生的少就算了,生了還要給別人帶別人養。我們的孩子也不太可能了解在大家庭長大的感覺是什麼。長大後,看到這些兔仔子,說她們沒規矩嗎?自己想想,時代不同了。以前,我家裡用餐是要等我爺爺從田裡忙回來,洗完澡,上桌吃飯,我們才能上桌一起用餐,而奶奶和媽媽是等到爺爺吃飽後,才會過來一起吃。很傳統吧!

是的,這一年的育嬰假,我們就是這樣過。為什麼我一定要準時下班,因為家裡有四口子在等我「開飯」。很多事,一定要長大且經歷過,你才會知道為什麼。小時候也不清楚,為什麼家裡的大人,天還沒亮就出門去工作,為什麼晚上還要等他們回來才能吃飯。不清楚,反正已經習慣了。

這一年,回到家除了寶貝們的迎接,另一件最高興的事就是,媽咪總是算好時間,然後對剛到家的我說:「飯菜都已經好了,馬上就能開動。」然後,從廚房送出一道道冒著白煙的飯菜。完了,我中毒了,少油少鹽少味素。你現在要我出去吃任何一家的飯物,對不起,通通不及格。

時間三小時與六小時的差別

我們回家,都能和父母親,或是爺爺奶奶聊著以前的種種。現在想想,我的孩子以後會跟我聊著什麼話題?他在保母或托育中心的種種嗎?我現在還是不時會與婆婆討論著「如果我們留在宜蘭…」、「如果我們回宜蘭…」這種話題。

這每每都讓我回想一篇網路留傳的故事:「薪水三萬與六萬的差別」。

我的要求不多,能有多一點時間可以陪著孩子,希望未來我能寫一篇「時間三小時與六小時的差別」,然後在網路上流傳。

這一年的來點點滴滴真的很棒,必定是我人生中重要的一年。

I love your, wife , daughters, flower ( my dog ).

我只能盡最大能力,做好老公、父親這兩個角色來回報你們給我的幸福快樂!

如果你經營過ixxx事業,找到無人的地方,給我3分鐘,你會懂的。

參考:

Windows - 加速 IE 8/ IE 9,榨乾對方Server

這篇文章很簡單,(寫Regisger一點也不簡單)
請參考:http://blog.darkthread.net/post-2011-08-24-ie-maxconnectionsperserver.aspx


解壓密碼:KKBruce

在 2011/8/29之下載過檔案的各位大大,那個檔案有問題而且是錯誤的(還好不能使用),請重新下載,我分為Windows 7 x64/x32兩個版本了。

本人學藝不精,蒙Will保哥不斷指教,檔案在 2011/9/6 進行第三次修改。

以下為聲明:


MaxConnectionsPerServerUpTo128_*.reg 檔依http://blog.darkthread.net/post-2011-08-24-ie-maxconnectionsperserver.aspx而製作,使用之前請先詳細閱讀Blog之文章。
使用之前,請先備份你的 Register 檔,如造成系統任何問題,本人不負任何責任,使用前之請考慮清楚。
Windows 7 x32, 使用 MaxConnectionsPerServerUpTo128_Win7x32.reg 註冊。
Windows 7 x64, 使用 MaxConnectionsPerServerUpTo128_Win7x64.reg 註冊。
預設開最大 128 條。請依需求修改。
以下為 2, 4, 8, 16, 32, 64, 128 的機碼,想修改可直接複製貼上到對應註冊檔中,重新點擊修改即可。
"iexplore.exe"=dword:00000002
"iexplore.exe"=dword:00000004
"iexplore.exe"=dword:00000008
"iexplore.exe"=dword:00000010
"iexplore.exe"=dword:00000020
"iexplore.exe"=dword:00000040
"iexplore.exe"=dword:00000080

我裡面的預設值直接設定為最大的 128 (十進位) / 80 (16進位),如果你不想放得那麼大,可自己修改內容值。


另,基本依黑大的文章裡 MSDN 的文章來看,從8、16、32、64、128,慢慢往上加應該是比較好的方式。


Jeffrey 黑暗大大的建言





雙面刃,使用之前請各位細思量!這只是把水管口從2吋變8吋或16吋,但出水量( Server )才是關鍵。


2011/9/4 新增兩張測試圖

我找了兩個「圖很多」的網站,然後測試值 16 的效果。


圖一:值16,測試一 (點擊看大圖)
圖二:值 16,測試二 (點擊看大圖)
圖二很明顯了吧!

2011/9/6 Register 檔案更新內容

我實在是第一次寫 Register 檔案給人家使用,造成大家的不便,實感抱歉。以下為目前檔案內容,請直接指教。最後再增加「參考」二篇,修改為下列機碼。@_@

MaxConnectionsPerServerUpTo128_Win7x32.reg

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER]
"iexplore.exe"=dword:00000080

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_SERVER]
"iexplore.exe"=dword:00000080

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER]
"iexplore.exe"=dword:00000080

找了台 Windows 7 x32 電腦,發現 Wow6432Node 下無任何可影響 IE 機碼。給自己一個經驗,在 Windows 7 環境下,一定要找 x32 / x64 比對、驗證。

MaxConnectionsPerServerUpTo128_Win7x64.reg

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER]
"iexplore.exe"=dword:00000080

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER]
"iexplore.exe"=dword:00000080

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER]
"iexplore.exe"=dword:00000080

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER]
"iexplore.exe"=dword:00000080


另外,我新增兩個刪除上述機碼的兩個註冊檔,可以回復 IE 預設值。

Delete_MaxConnectionsPerServerUpTo128_Win7x32.reg

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER]
"iexplore.exe"=-

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_SERVER]
"iexplore.exe"=-

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER]
"iexplore.exe"=-

Delete_MaxConnectionsPerServerUpTo128_Win7x64.reg

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER]
"iexplore.exe"=-

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER]
"iexplore.exe"=-

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER]
"iexplore.exe"=-

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER]
"iexplore.exe"=-

另香港網友Tony提供批次檔經Will保哥加了註解,一併提供出來給大舉。

@echo off

set max=32

:: 修改個人設定
REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /V MaxConnectionsPer1_0Server /t REG_DWORD /d %max% /f
REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /V MaxConnectionsPerServer /t REG_DWORD /d %max% /f

:: 修改電腦設定(x64或x86)
REG ADD "HKLM\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER" /V iexplore.exe /t REG_DWORD /d %max% /f
REG ADD "HKLM\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER" /V iexplore.exe /t REG_DWORD /d %max% /f

:: 修改電腦設定(Wow6432Node)
IF NOT EXIST "%ProgramFiles(x86)%" GOTO not_64-bit_OS
REG ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER" /V iexplore.exe /t REG_DWORD /d %max% /f
REG ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER" /V iexplore.exe /t REG_DWORD /d %max% /f

:not_64-bit_OS
pause

參考:

讀書心得 - 三千億傳奇之郭台銘的鴻海帝國

三千億傳奇-郭台銘的鴻海帝國我看的這本書為2002年版,2005年標題為「五千億傳奇-郭台銘的鴻海」帝國,內容裡的經典語錄,你可以上網找一下。像這裡 郭台銘的鴻海帝國 或 Google Doc 快速檢視 都可以看到精華部份,甚至有還一本解碼郭台銘語錄:超越自我的預言(郭語錄),買回來拜一下。

為什麼看這本9年前的書?沒什麼,因為它放了9年,也是應該還個公道的時候。不過,從這書中,我也看到一些問題點。

心得


先談談這本「三千億傳奇-郭台銘的鴻海帝國」,「第一部 特寫郭台銘」讓人看到郭台銘這個人的另一面,也是我覺得最好看的一部份,因為這裡面談的是「人」不是「企業」,以金字塔來形容,把金字塔分三部分,最低下的人看第一部,中間要往上衝的管理人,看第二部 徒手創業,最上面的經理人,看第三部 爭霸全球。

我發現,郭台銘的智慧是那種「人生智慧」,什麼是人生智慧?打個比方,我家有一套三集的靜思語,那種人生智慧是高階、意境、修養…等形態的人生智慧。但郭台銘的人生是走出來的,是拚出來的,是苦出來的,比較像苦行僧,一步一腳印所得到的人生智慧。

這所帶出的wisdom,說真的,他願意說出來之前,如果可以,有幾人願意跟走一模一模的路。不要看成功之時,要看難關,他是如何關關過

一句:
為錢做事,容易累;
為理想做事,能夠耐風寒;
為興趣做事,則永不倦怠。
道出了他選擇了所愛,愛他所選。

問題


也因為這是9年前的書,所以我也看到一些問題。台灣這些大企業的老闆們,都很可憐 ( 對不起,我只是一個小小沙丁魚,應該沒資格說你們 )。
  • 想退,不能退。
  • 退了,不能休。
  • 休了,還要做,
  • 做了,又要出。

郭台銘、張忠謀…都差不多,郭台銘說想退休來幫助更多中小企業,結果呢?台灣企業( or 媒體 )太喜歡神話,神話那位帶頭衝的人。經營之神王永慶先生都已經過世多久了,也還是能拿出來炒個新聞,沒有你台塑就全是

反觀國外大企業,例如,讓我有飯吃的 Microsoft ( 我學的、架的、用的、寫的… ),Bill Gates 退就退,你也沒聽說因為什麼事,他還要重回 Microsoft 去管理什麼事。

能活十年、三十年、五十年、一百年、百年以上的企業,算一算,一定是一個比一個少,但那五十年以上,甚至百年以上的企業,決不是由一個神話來支持,決不是由一個人來經營。我不敢說要怎麼做,我也沒那個能力,只是看看此書,對照9年來發生的事,所產生的一些感想。

結論


不變即是變。2002年書中說郭台銘不愛曝光不愛媒體,現在呢?65歲的退休,為興趣做事呢?最近路上常看到一政治廣告文句:「現在決定未來」,我會說,放屁,我們連下一秒都無法決定會發生什麼事了,還未來呢!狗屁不通。( 我無意談論政治,只是就文字的邏輯討論 )

鴻海市值已經破「兆」元,已經不是三千億、五千億,很高興台灣能有這麼一家成功的企業,但也希望不要走王家神話之路,回歸到企業的本質,讓鴻海成為鴻海,而不是如標題「郭台銘的鴻海帝國」,改為「鴻海的百年帝國」,不更振奮人心。

以下這句我很喜歡:
人沒有天生的窮命和賤命,只有你是什麼樣的心態來磨練自己。
共勉之。

童言童語 - 妳跟我對不起

媽咪的育嬰假正式結束了,經過了一、二個月生活上的調整,家庭的生活模式才慢慢又穩定下來。

有一天,我們要先帶寶貝出門去看醫生,然後才送去托育中心,就在途中,大寶貝提出了她的問題。

大寶貝:媽咪,等一下我們要去張老師那裡嗎?
大公主:對呀,看完醫生伯伯就要帶妳們去。
大寶貝:為什麼我們要去張老師那裡?
大公主:因為爸比和媽咪都要去上班,我們去上班就沒辦法照顧妳們呀!
大寶貝:為什麼你們要去上班? 大公主:我們去上班才能賺錢錢,賺到錢錢,我們才有辦法帶妳去買玩具、吃愛吃的東西。
大寶貝:那你們跟我對不起?
大公主:…XD

你只能看到兩個眼神凝重的父母親,用很沉重的回氣說:「寶貝,Sorry,對不起!」

年少不努力,老大被兒欺!
哈!

ASP.NET MVC - 在 MVC 使用ASP.NET Web Form的方法下載檔案

前言

原文參考:Trigger file downloads with a MVC 3 controller action

在 ASP.NET MVC 中,一般是使用 FileResult 來回傳檔案資料流給 Client,以進行檔案下載等動作。這我們在「ASP.NET MVC - 單一檔案與多檔案上傳及下載管理」最後一部份及「ASP.NET MVC - 檔案下載使用非主鍵,例如Name, GUID」都能清楚看到。

開頭原文是使用 ASP.NET Web Form 的 Response.BinaryWrite() 的方法,就像「透過資料庫上傳下載檔案」的使用一樣,算是ASP.NET Web From + ASP.NET MVC 二合一下載方法,因為原文為 C#,所以我改寫為 Visual Basic。

那為什麼我要特別轉介紹這個 ASP.NET Web Form 下載方法,如何在 ASP.NET MVC 裡使用?原因很簡單,因為我們會碰到一個「阿豆仔」不會碰到的問題,什麼問題?你有沒有下載過「中文檔案名稱」的檔案?例如,「產品規格.pdf」、「全系列產品.xls」、「產品升級說明.doc」…,你可以試試看,在原始 ASP.NET MVC 中使用 FileResult 來讓使用者下載中文檔案名稱的檔案,你會發現檔案名稱除 Firefox 3.6 (註1) 之外,其他瀏覽器都會是亂碼。原因是 ASP.NET MVC 走的規格太新 ( RFC2231 ),瀏覽器來不及實作。不過,現在瀏覽器更新速度很快,就算最近的新版本瀏覽器都已經支援此規格,但我們無法保證使用者的瀏覽器版本,還是會產生亂碼問題。

註1:Will保哥所著:「ASP.NET MVC 2 開發實戰」,第6章第143~148頁,有針對ASP.NET MVC 的中文檔案名稱下載的討論。有興趣者請自行參考。

那怎麼辦,如果你真的有這種需求?那就必須回歸使用 ASP.NET Web Form 的下載方法,這樣我們就能確保下載的檔案名稱不管是中文還是英文都能很正常顯示及下載。不過再提醒,除非萬不得以,我是強烈建議檔案名稱還是使用英文來命名

在 MVC 實作 ASP.NET Web Form 下載

Step 1:我們先在根目錄新增一個 Extensions 目錄,然後新增一個 GetFileData.vb Class。

Imports System.Runtime.CompilerServices 
Imports System.IO 
public Module GetFileData 
    ''' <summary>
    ''' 擴充方法:確認檔案是否存在,存在將檔案讀出回傳
    ''' </summary>
    ''' <param name="fileName">檔案名稱</param>
    ''' <param name="filePath">檔案路徑</param>
    <Extension()>
    Function GetFileData(fileName As String , filePath As String) As Byte()
         
        Dim fullFilePath = String.Format("{0}/{1}", filePath, fileName )
        If Not System.IO.File.Exists(fullFilePath ) then 
            Throw New FileNotFoundException("檔案不存在!", fileName )
        End If

        Return System.IO.File.ReadAllBytes(fullFilePath)
    End Function
End Module

Step 2:在 Extensions 目錄中新增一個 FileDownloadResult.vb 類別,這裡我們有個重大任務,我們自己寫一個回傳類別,以 ASP.NET Web Form 的方法啟動檔案下載的動作。

''' <summary>
''' Inherits ContentResult, then Overrides ExecuteResult
''' </summary>
Public Class FileDownloadResult
    Inherits ContentResult

    Private _fileName As String
    Private _fileData As Byte()

    Sub New(fileName As String, fileData As Byte())
        _fileName = fileName
        _fileData = fileData
    End Sub

    ''' <summary>
    ''' 覆寫執行結果( ExecuteResult )
    ''' </summary>
    Public Overrides Sub ExecuteResult(context As System.Web.Mvc.ControllerContext)
        If String.IsNullOrEmpty(Me._fileName) Then
            Throw New Exception("需要檔案名稱!")
        End If

        If Me._fileData Is Nothing Then
            Throw New Exception("檔案必須有內容!")
        End If

        ' 使用 ASP.NET Web Form 方法進行檔案資料流輸出
        Dim contentDisposition = String.Format("attachment; filename={0}", Me._fileName)
        ' 加入 AddHeader,需要指定 Content-Disposition, 重點是檔案名稱
        context.HttpContext.Response.AddHeader("Content-Disposition", contentDisposition)
        ' 指定MIME,這個地方可以加強,可依檔案類型給正確的MIME。
        ' 為尊重原作者,我就不修改了。
        ContentType = "application/force-download"
        ' 輸出檔案
        context.HttpContext.Response.BinaryWrite(Me._fileData)
    End Sub
End Class

這裡我們也學到可以繼承 ActionResult 的類別,然後修改成自己想要功能。

Step 3:新增一個 Controller \ FilesController.vb 來進行檔案搜尋及下載的動作。

Public Class filesController
    Inherits System.Web.Mvc.Controller

    ''' <summary>
    ''' 注意,回傳類別是FileDownloadResult
    ''' </summary>
    ''' <param name="file">檔案名稱</param>
    Function Download(file As String) As FileDownloadResult
        Try
            ' file.GetFileData() 是我們前面撰寫的擴充方法
            ' 確認檔案是否存在,存在,將檔案讀出回傳
             ' 我們的目錄設定在根目錄下的 ~/Files
            Dim fileData = file.GetFileData(Server.MapPath("~/Files"))
            ' 進行檔案下載的動作
            ' 因為會觸發我們覆寫 ExecuteResult 方法
            Return New FileDownloadResult(file, fileData)
        Catch ex As Exception
            Throw New HttpException(404, "找不到檔案!")
        End Try
    End Function
End Class

Step 4:在相關 View ,撰寫測試下載的 ActionLink()

我們的目錄設定在根目錄下的 ~/Files,請自行準備好相關測試檔案。

<div>
    <ul>
        <li><%: Html.ActionLink("Sales", "Download", New With {.Controller = "Files", .file="Sales.7z"}) %></li>
        <li><%: Html.ActionLink("產品型錄", "Download", New With {.Controller = "Files", .file="產品型錄.7z"}) %></li>
        <li><%: Html.ActionLink("Opps!", "Download", New With {.Controller = "Files", .file="Opps.7z"}) %></li>
        <li><%: Html.ActionLink("產品規格", "Download", New With {.Controller = "Files", .file="產品規格.7z"}) %></li>
    </ul>
</div>

結論

你可以參考前面「ASP.NET MVC - 單一檔案與多檔案上傳及下載管理」來修改此範例,增加資料庫管理的功能,那會更棒。或是提供一個「中介」的 Action 去判斷使用者的瀏覽器,如果是支援 RFC2231 瀏覽器 ( 這部份就留給各位去測試,或是有人測試願意回報給我,我也會非常感謝 ),就使用ASP.NET MVC 的 FileResult 去下載,不然就使用 ASP.NET Web Form 的方法去下載。

如果你在讓使用者下載檔案時,需要處理中文檔案名稱的問題,才會建議使用 ASP.NET Web Form 的方法,這也讓我們知道每個東西都有優點,不是最新就是最好,合適的地方用合適的方法,適才適用最重要。

透過幾篇的討論,現在我們使用 ASP.NET MVC 不管是上傳、下載、中文檔案名稱、英文檔案名稱,通通不是問題了,你應該可以很輕鬆處理。

參考

ASP.NET MVC - About ViewData, ViewBag, TempData

在 ASP.NET MVC 2 時,我們要由 Controller 傳遞資料給 View,可以使用 ViewData、TempData。
在 ASP.NET MVC 3 時,除了原先的 ViewData、TempData,還新增一個 ViewBag。

我們今天簡單討論一下這三者。

  • 傳遞小量資料:使用 ViewData、ViewBag 都一樣。
  • 傳遞大量或複雜資料:使用 ViewModel。
  • 由現在 to 下一個 Http Request:使用 TempData ( Http 302 status )

ViewData 物件

它是一個 Dictionary Object ( ViewDataDictionary Class ),你能放任何資料進去,使用「Key / Value」語法存取。

ViewBag 物件

它和 ViewData 物件一樣,也能放任何資料進去,但更棒的事,ViewBag 能產生「動態屬性」

例如,

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Function Index() As ActionResult
        ViewData("Message1") = "歡迎使用 ASP.NET MVC!"
        ViewBag.Message2 = "歡迎使用 ASP.NET MVC 3!"

        Return View()
    End Function

    Function About() As ActionResult
        Return View()
    End Function
End Class

我們看 Index.aspx ( View )

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Index
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%: ViewData("Message1") %></h2>
    <h2><%: ViewBag.Message2 %></h2>
</asp:Content>

如果我們在 Controller / Index 裡把 ViewData 的 Key 設為 Message,然後把 ViewBag 的動態屬性也設為 Message,你會發現後面的 Message 的值會覆蓋前面的,以上例來說,將 View 全部改為 Message,將會全部顯示「"歡迎使用 ASP.NET MVC 3!"」

我最常使用在傳遞 Dropdown lists 的值給 View。

TempData 物件


TempData 很清楚的,是拿來存放「暫時性」資料,但它有一特性,使用 Redirect 相關 ActionResult 之後,ViewData 或 ViewBag 的資料都會不見。通常是在,Action --> Action 有需要傳遞資料時,就會使用 TempData。我們修改範例,


Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Function Index() As ActionResult
        ' Message1 是 Key,  "歡迎使用 ASP.NET MVC!" 是 Value
        ViewData("Message1") = "歡迎使用 ASP.NET MVC!"
        ' Message2 是動態屬性
        ViewBag.Message2 = "歡迎使用 ASP.NET MVC ViewBag!"
        ' TempData 也是 Key / Value 存取
        TempData("Message3") = "歡迎使用 ASP.NET MVC TempData"
        
        '測試 ViewData, ViewBag, TempData 三者經過 Redirect 後的結果
        Return RedirectToAction("About")
    End Function

    Function About() As ActionResult
        Return View()
    End Function
End Class

修改 About.aspx

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="aboutTitle" ContentPlaceHolderID="TitleContent" runat="server">
    About
</asp:Content>
<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2>About</h2>
    <div>
        <h2>Message1 : <%: ViewData("Message1") %></h2>
        <h2>Message2 : <%: ViewBag.Message2 %></h2>
        <h2>Message3 : <%: TempData("Message3") %></h2>
    </div>
</asp:Content>

讓畫面說話吧!


而且 TempData 只要經過取得,資料就會消失,也就是「存也一次,取也一次」,這就是 TempData 的生命週期。

參考:

重構 - Refactoring Lists

如果各位有接觸物件導向程式設計(OOP),有幾本書大概很難不買,「重構-改善既有程式的設計」、「Refactoring - Improving the Design of Existing Code」,侯捷大師還很用心提供了前六章的免費PDF電子檔。

原始下載點:refactoring-ch1-ch6.pdf
備份下載點:refactoring-ch1-ch6.pdf

以下只是書本首頁有個「重構列表, Refactoring Lists」,為查詢方便,記錄一下。
  1. Add Parameter ( 添加參數 )
  2. Change Bidirectional Association to Unidirectional ( 將雙向關聯改為單向 )
  3. Change Reference to Value ( 將引用物件改為實值物件 )
  4. Change Unidirectional Association to Bidirectional ( 將單向關聯改為雙向 )
  5. Change Value to Reference ( 將實值物件改為引用物件 )
  6. Collapse Hierarchy ( 摺疊繼承體系 )
  7. Consolidate Conditional Expression ( 合併條件式 )
  8. Consolidate Duplicate Conditional Fragments ( 合併重複的條件片段 )
  9. Convert Procedural Design to Objects ( 將程序式設計轉化為物件設計 )
  10. Decompose Conditional ( 分解條件式 )
  11. Duplicate Observed Data ( 複製「被監視資料」 )
  12. Encapsulate Collection ( 封裝群集 )
  13. Encapsulate Downcast ( 封裝「向下轉型」動作 )
  14. Encapsulate Field ( 封裝欄位 )
  15. Extract Class ( 提煉類別 )
  16. Extract Hierarchy ( 提煉繼承體系 )
  17. Extract Interface ( 提煉介面 )
  18. Extract Method ( 提煉方法 )
  19. Extract Subclass ( 提煉子類別)
  20. Extract Superclass ( 提煉超類別 )
  21. From Template Method ( 塑造模板函式 )
  22. Hide Delegate ( 隱藏「委託關係」 )
  23. Hide Method ( 隱藏某個函式 )
  24. Inline Class ( 將類別內聯化 )
  25. Inline Method ( 將函式內聯化 )
  26. Inline Temp ( 將暫時變數內聯化 )
  27. Introduce Assertion ( 引入斷言 )
  28. Introduce Explaining Variable ( 引入解釋性變數 )
  29. Introduce Foreign Method ( 引入外加函式 )
  30. Introduce Local Extension ( 引入區域性擴展 )
  31. Introduce Null Object ( 引入 Null 物件 )
  32. Introduce Parameter Object ( 引入參數物件 )
  33. Move Field ( 搬移欄位 )
  34. Move Method ( 搬移方法 )
  35. Parameterize Method ( 令函式攜帶參數 )
  36. Preserve Whole Object ( 保持物件完整 )
  37. Pull Up Constructor Body ( 建構式本體上移 )
  38. Pull Up Field ( 欄位上移 ) 
  39. Pull Up Method ( 函式上移 )
  40. Push Down Field ( 欄位下移 )
  41. Push Down Method ( 函式下移 )
  42. Remove Assignments to Parameters ( 移除對參數的賦值動作 )
  43. Remove Control Flag ( 移除控制旗標 )
  44. Remove Middle Man ( 移除中間人 )
  45. Remove Parameter ( 移除參數 )
  46. Remove Setting Method ( 移除設值函式 )
  47. Rename Method ( 重新命名函式 )
  48. Replace Array with Object ( 以物件取代陣列 )
  49. Replace Conditional with Polymorphism ( 以多型取代條件式 )
  50. Replace Constructor with Factory Method ( 以工廠函式取代建構式 )
  51. Replace Data Value with Object ( 以物件取代資料值 )
  52. Replace Delegation with Inheritance ( 以繼承取代委託 )
  53. Replace Error Code with Exception ( 以異常取代錯誤碼 )
  54. Replace Exception with Test ( 以測試取代異常 )
  55. Replace Inheritance with Delegation ( 以委託取代繼承 )
  56. Replace Magic Number with Symbolic Constant ( 以字面常數取代魔術數字 )
  57. Replace Method with Method Object ( 以函式物件取代函式 )
  58. Replace Nested Conditional with Guard Clauses ( 以衛述句取代巢狀條件式 )
  59. Replace Parameter with Explicit Methods ( 以明確函式取代參數 )
  60. Replace Parameter with Method ( 以函式取代參數 )
  61. Replace Record with Data Class ( 以資料類別取代記錄 )
  62. Replace Subclass with Fields ( 以欄位取代子類別 )
  63. Replace Temp with Query ( 以查詢取代暫時變數 )
  64. Replace Type Code with Class ( 以類別取代型別代碼 )
  65. Replace Type Code with State/Strategy ( 以State/Strategy 取代型別代碼 )
  66. Replace Type Code with Subclasses ( 以子類別取代型別代碼 )
  67. Self Encapsulate Field ( 自我封裝欄位 )
  68. Separate Domain from Presentation ( 將領域和表述/顯示分離 )
  69. Separate Query from Modifier ( 將查詢函式和修改函式分離 )
  70. Split Temporaty Variable ( 剖解暫時變數 )
  71. Substitute Algorithm ( 替換你的演算法 )
  72. Tease Apart Inheritance ( 梳理並分解繼承體系 )

希望未來能有機會,慢慢為每個項目加上Link,並說明我碰到的情況,期許自己更上一層樓。

加油!

ASP.NET MVC - 使用MVC MiniProfiler測試您的網頁跑多快

在MVC 3專案中,NuGet 指令:Install-Package MiniProfiler

在修改 Global.asax.vb

Imports MvcMiniProfiler

Sub Application_BeginRequest()
    ' 如果是本機連線,MiniProfiler才啟用
    If Request.IsLocal() Then
        MiniProfiler.Start()
    End If
End Sub

Sub Application_EndRequest()
    MiniProfiler.Stop()
End Sub

接下來,我們修改Site.Master,
  1. 先載入 jQuery
  2. MiniProfiler的Render設定

<!-- MVC預設有載入jQuery,另在 </head>之前加上以下程式碼即可 -->
<%: MvcMiniProfiler.MiniProfiler.RenderIncludes() %>
</head>

下一步,是在 Controller 裡撰寫測試程式碼,測試程式碼必須使用 Using ~ End Using,例如,

Imports MvcMiniProfiler

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Function Index() As ActionResult
        ViewData("Message") = "歡迎使用 ASP.NET MVC!"

        ' 取得現在執行HttpContext內的MiniProfiler
        Dim mp As MiniProfiler = MiniProfiler.Current()

        ' Step,現在步驟
        Using mp.Step("Doing complex stuff")
            Using mp.Step("Step A")
                ' 做一些事
                System.Threading.Thread.Sleep(100)
            End Using

            Using mp.Step("Step B")
                ' 做一些事
                System.Threading.Thread.Sleep(250)
            End Using
        End Using

        Return View()
    End Function

    Function About() As ActionResult
        Return View()
    End Function

End Class

讓我們將網頁執行起來,來看結果。


我們可以看到左上角多了一個數字,我們點擊一下,看內容。


對照一下我們的程式,第一次網頁啟動花費約二秒,Step A 我們Sleep(100),Step B我們Sleep(250),加一加約 2.3 秒。透過這樣的方法,可以讓我們非常明確了解,每一段程式碼執行的效率。就像李昌鈺博士所說:
「有一分證句,說一分話。」

資料庫測速

MiniProfiler還可以針對網頁與資料庫之間進行測速,不過我怎麼測都不成功,但還是有測出一些心得,所以寫下來。

他們會要你改寫 web.config ,例如,

<remove invariant="MvcMiniProfiler.Data.ProfiledDbProvider" />
<add name="MvcMiniProfiler.Data.ProfiledDbProvider"
     invariant="MvcMiniProfiler.Data.ProfiledDbProvider"
     description="MvcMiniProfiler.Data.ProfiledDbProvider"
     type="MvcMiniProfiler.Data.ProfiledDbProviderFactory, MvcMiniProfiler, Version=1.7.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3" />

測試時,一直出現錯誤,說他不認識這堆東西,後來我去查最上層的(C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config),要多加一個DbProviderFactories才對。

加在 <configuration> 之下。

<system.data>
    <DbProviderFactories>
        <remove invariant="MvcMiniProfiler.Data.ProfiledDbProvider" />
        <add name="MvcMiniProfiler.Data.ProfiledDbProvider"
             invariant="MvcMiniProfiler.Data.ProfiledDbProvider"
             description="MvcMiniProfiler.Data.ProfiledDbProvider"
             type="MvcMiniProfiler.Data.ProfiledDbProviderFactory, MvcMiniProfiler, Version=1.7.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3" />
    </DbProviderFactories>
</system.data>

然後修改 Global.asax.vb

Sub Application_Start()
    AreaRegistration.RegisterAllAreas()

    RegisterGlobalFilters(GlobalFilters.Filters)
    RegisterRoutes(RouteTable.Routes)

    ' 新增以下MiniProfiler設定
    MiniProfiler.Settings.SqlFormatter = new MvcMiniProfiler.SqlFormatters.SqlServerFormatter()
    ' SqlCeConnectionFactory 必須傳入資料庫連線字串
    Dim factory = new System.Data.Entity.Infrastructure.SqlCeConnectionFactory("Data Source=.\sqlexpress;Initial Catalog=Northwind;Integrated Security=True")
    Dim profiled = new MvcMiniProfiler.Data.ProfiledDbConnectionFactory(factory)
    System.Data.Entity.Database.DefaultConnectionFactory = profiled
End Sub

而且在測試過程中發現,我是使用 Entity Framework 4.1 (DbContext),目前看來是還無法使用資料庫部份功能,因為現在 MiniProfiler 目前只支援 ObjectContext 物件,我都還沒傳進去就 Visual Studio 就已經跟我報錯了!@_@

另外小小抱怨一下,它的說明文件嚴重不足,

參考資料:

ASP.NET MVC - Controller Inspector and Route Debugger

在 NuGet 下指令 Install-Package MvcHaack.ControllerInspector

在要檢查的 Controller 後面加上一個「?inspect」參數即可。例如,我想在HomeController 下的 About Action,那網址會是「http://localhost:3754/Home/About?inspect」這樣。以參數方式來使用,你就能看到整個 Controller 相關資訊。



如果你還需要更強大的除錯功能,Phil Haack還有提供一個「ASP.NET Routing Debugger」,一樣,你可以在 NuGet 下搜尋「routedebugger」或下「Install-Package routedebugger」安裝即可。

重新編輯一下專案,你會發現畫面最下方出現 Routing 資訊了。


你不需要在 Application_Start() 程序中加任何程式碼。( ASP.NET Routing Debugger 文章是比較舊的使用方式 )

我們開啟 NuGet 的 Packge Visualizer,


現在是透過 MvcControllerInspector 類別來控制。一個「?inspect」能讓你在ASP.NET MVC 的路上快樂許多,何樂而不背呢?

[2011/8/24 補充:關閉 routedebugger]

當你使用了 routedebugger 後,你會發現每一頁都會出現 Routing 資訊,如果你要暫時 disable 這個功能,必須從 web.config 裡找 RouteDebugger:Enabled 項目,

  <appSettings>
    <add key="webpages:Version" value="1.0.0.0" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="RouteDebugger:Enabled" value="true" />
  </appSettings>

把 RouteDebugger:Enabled 後面的 value="false" 即可關閉 routedebugger 模式。


參考:

讀書心得 - 沉思錄:一念之間改變人生

時間:20011/8/14 4:40 AM ( 100/7/15 )

一本值的一讀再讀的好書:沉思錄 ( Marcus Aurelius 著)

開卷第一頁,才看完就讓我起雞皮疙瘩。

《沉思錄》第六卷
如果有一件事對你來說,是難以完成的,
不要認為其他人也不可能完成。
如果完成這件事,對其他人來說是可能的,
想必你也能完成它。

讓我們努力說服人們:
當正義的原則指向這條路,就循著這條路前進。
如果有人強力擋住你的去路,就把它當成自我的鍛鍊,
不論是披荊斬棘,或清除爛泥,都是一種收穫。

不管是人生、心靈、自傳、小說、愛情、古典、勵志、財經或是技術…,看過的書不算少數,但一段小小的話就讓我起雞皮疙瘩,這是為什麼?我的心在想什麼,我的靈感受到什麼,為什麼我的身體會有這種反應。

凌晨起來,一頁一頁的翻下去。

我看,我想,我問。

我看

不是因為他的智慧,關於有智慧的書太多了,但知易行難,也是之所以這些智慧成為智慧,為何不是一般人可得可行的原因。沉思錄中的普世價值,就可行性而言,比起其他真言、真理高出許多。如果書名「沉思」,讓我們進入「心的世界」。

我想

每看完一小篇語錄札記,不會讓我更聰明,確能讓我那心靈轉盤有了潤滑,開始轉動。它就像除鏽劑,快速進入內心,找到你生鏽卡住的地方,潤滑,然後驅動。讓你可以如同坐阿里山小火車,有機會看那心中世界的山水白雲。

我問

這才發現,智者不是多會回答問題,而是多會問。透過一問再問,慢慢深入,進而追求真理。自省再自省。都已經幾千年了,我們還在追求古人的智慧。前人留給我們太多,希望未來人也是這樣看我們。

ASP.NET MVC 3 Areas Can't Run Bug ( VB Only)

我們開一個ASP.NET MVC 3 (Visual Basic)的專案,然後依「逐步解說:使用區域組織 ASP.NET MVC 應用程式」練習題,題目很簡單,新增兩個Area,一個Blog,一個Dashboard。

在Areas\Blog\Controllers下新增BlogController及ShowRecent 和 ShowArchive兩個Action及View。
在Areas\Dashboard\Controllers下新增DashboardController及AddPost 和 EditPost兩個Action及View。

在Views\Shared\Site.Master,修改

<ul id="menu">              
    <li><%=Html.ActionLink("Home", "Index", "Home", New With {.area = ""}, Nothing)%></li>
    <li><%=Html.ActionLink("Blog", "ShowRecent", "Blog", New With {.area = "Blog"}, Nothing)%></li>
    <li><%=Html.ActionLink("Dashboard", "AddPost", "Dashboard", New With {.area = "Dashboard"}, Nothing)%></li>
    <li><%=Html.ActionLink("About", "About", "Home", New With {.area = ""}, Nothing)%></li>
</ul>
點擊Blog產生錯誤訊息
點擊Dashboard產生錯誤訊息
我重開一個MVC 2的專案測試,Areas的使用很正常。我又換了台電腦,開一個MVC 3專案(VB),一模一樣的內容,在MVC 3的專案的Areas就是會產生以上的錯誤訊息,但C# MVC 3專執行很正常。 我知道Areas要注意命名空間,但不管我在 Global.asax 或 Areas\Blog\BlogAreaRegistration.vb 裡修改 MapRoute 命名空間,還是一樣的錯誤訊息。 我們來看BlogAreaRegistration.vb,這是你新增Areas時,系統自己產生的檔案,用意是在註冊路由。
Namespace Mvc3Area.Areas.Blog
    Public Class BlogAreaRegistration
        Inherits AreaRegistration

        Public Overrides ReadOnly Property AreaName() As String
            Get
                Return "Blog"
            End Get
        End Property

        Public Overrides Sub RegisterArea(ByVal context As System.Web.Mvc.AreaRegistrationContext)
            context.MapRoute( _
                "Blog_default", _
               "Blog/{controller}/{action}/{id}", _
                New With {.action = "Index", .id = UrlParameter.Optional} _
                )
        End Sub
    End Class
End Namespace
其實C#的Code差不多,以下為C#的程式碼。
using System.Web.Mvc;

namespace Mvc3AreasC.Areas.Blog
{
    public class BlogAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "Blog";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "Blog_default",
                "Blog/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}
我中斷點設定 context.MapRoute 這一段,然後發現原來是Visual Basic 的 Namespace 有問題。如果我把 BlogAreaRegistration.vb 裡的 Namespace 註解前後來比較: 註解前:Mvc3Area.Mvc3Area.Areas.Blog.* 註解後:Mvc3Area.* 我們可以試著在根目錄Controllers產生一個 UserController.vb ,發現他的 Namespace 為 「Mvc3Area」,即專案名稱。也就是說,在MVC 3使用Visual Basic所產生 *AreaRegistration.vb 的是不正確的,您必須將專案名稱後的命名全部去除,即可讓 Areas 正常運作。
' 修改Mvc3Area.Areas.Blog
Namespace Mvc3Area
    ' 其他不用修改
End Namespace
修正命名空間後,您的 Areas 程式應該就能正常運作了。

ASP.NET MVC - 檔案下載使用非主鍵,例如Name, GUID

我們在前一篇「單一檔案與多檔案上傳及下載管理」有一段下載檔案的程式碼,如下:

Function Download(id As Integer) As ActionResult
        Using db As New FilesEntities

            ' 取得檔案資訊
            Dim getfile = (From f In db.FileDown Where f.FileId = id Select f).FirstOrDefault()

                If getfile.FileName IsNot Nothing Then
                    Dim FilePath As String = Server.MapPath("~/Files/" &amp; getfile.FileName)

                    ' 進行下載
                    If System.IO.File.Exists(FilePath) Then
                        Return File(FilePath, getfile.FileType, getfile.FileName)
                    End If
                Else
                    ' 回應錯誤
                    Return Content("無法下載檔案!")
                End If
            End Using

            Return RedirectToAction("Index")
 End Function

一般而言,id 會是主鍵(PK),那如果我不想使用主鍵可不可以,也是可以,你只需要把LINQ那段語法修改一下即可,例如,我想使用檔案名稱來下載:

' 記得要傳入name 參數
Function DownloadByName(name As String) As ActionResult
    Dim getfile = (From f In db.FileDown Where f.FileName = name Select f).FirstOrDefault()
    ' 其他一樣

不過像id, name 這種都很好猜,我可以手動輸入就可以把檔案下載回來。如果是這樣,那我們還可以使用GUID來讓使用者下載。

' 記得guid 型別是 Guid
Function DownloadByGuid(guid As Guid) As ActionResult
    Dim getfile = (From f In db.FileDown Where f.rowguid= guid Select f).FirstOrDefault()
    ' 其他一樣

另外,為確保傳入為Guid,再加強一下程式:

Function DownloadByGuid(guid As String) As ActionResult
    Dim parseGuid As Guid = System.Guid.Parse(guid)
    Dim getfile =  (From f In db.FileDown Where f.rowguid= guid Select f).FirstOrDefault()

經過 Guid.Parse() 的好處是,我可以使用Try ... Catch 直接進行錯誤處理。最後程式修改為:

Function DownloadByGuid(guid As String) As ActionResult
    Try
        Dim parseGuid As Guid = System.Guid.Parse(guid)
        Dim getfile =  (From f In db.FileDown Where f.rowguid= guid Select f).FirstOrDefault()

        If getfile.FileName IsNot Nothing Then
            Dim FilePath As String = Server.MapPath("~/Files/" &amp; getfile.FileName)

            ' 存在,進行下載
            If System.IO.File.Exists(FilePath) Then
                Return File(FilePath, getfile.FileContentType, getfile.FileName)
            End If
        End If
    Catch ex As ArgumentNullException
        ViewBag.Message = ex.Message
    Catch ex As FormatException
        ViewBag.Message = ex.Message
    Catch ex As Exception
        ViewBag.Message = ex.Message
    End Try

    Return RedirectToAction("Index")
End Function

下載網址會是這樣:「http://localhost:15454/File/DownloadByGuid?guid=aeb238f8-d339-4997-bd9b-111c60906a15」,先把guid當成String,然後System.Guid.Parse(guid) 轉換為 Guid型別,成功才進行 LINQ 查詢,有資料就下載。

ASP.NET MVC - 單一檔案與多檔案上傳及下載管理

之前在 ASP.NET 寫過一篇「透過資料庫上傳下載檔案」,不過此方法有些缺點,例如,資料庫肥大,這些進入資料庫的檔案都是二進位儲存,所以就算是使用資料庫壓縮,會讓資料庫長的肥肥胖胖的。再來,如果你的架構比較大,是將Web Application與Database分開不同伺服器,那麼Web Application與Database之間的頻寬、Disk I/O成本也會大些。

我們來改來方式,將檔案上傳至Web Application特定目錄下,然後將此上傳檔案的資訊儲存至資料庫,這些資訊都是文字,所以對資料庫大小影響不大,就算是上萬十萬筆資訊,文字資料的壓縮率是非常不錯的。當我要下載檔案時,從資料庫取出檔案資訊,然後由Web Application的特定目錄讀出檔案,傳送給Browser進行下載。

以下以ASP.NET MVC實作,會有兩個部分,一是單一檔案上傳,二是多檔案上傳。

資料庫資料


我在 App_Data 裡新檔一個 Files.mdf,表格名稱 FileDown,Schema為

FileId, int, PK
FileName, nvarchar(50)
FileSize, nvarchar(50)
FileType, nvarchar(50)
FileVersion, nvarchar(50)
PostDate, datetime2(7)
UploadDate, datetime2(7)
rowguid, uniqueidentifier

在 Models 目錄下建立 FileModel.edmx 及 FileModel.Context.tt,FileModel.tt。(Entity Framework 4.1)

MVC 單一檔案上傳


新增 FileController.vb,把我們的架構先寫出來。

Imports System.IO

Public Class fileController
    Inherits System.Web.Mvc.Controller

    ' 顯示檔案列表
    Function Index() As ActionResult
        Return View()
    End Function

    ' 單一檔案上傳表單
    Function Upload() As ActionResult
        Return View()
    End Function

    ' 處理單一檔案上傳
    <HttpPost()>
    Function Upload(upfile As HttpPostedFileBase, formData As FormCollection) As ActionResult
        Return View()
    End Function

    ' 多檔案上傳表單
    Function MultiUpload() As ActionResult
        Return View()
    End Function

    ' 處理多檔案上傳
    <HttpPost()>
    Function MultiUpload(form As FormCollection) As ActionResult
        Return View()
    End Function

    ' 處理檔案下載
    Function Download(id As Integer) As ActionResult
        Return View()
    End Function

我們一個一個來處理。

    ' 顯示檔案列表
    Function Index() As ActionResult
        Dim db As New FilesEntities
        Return View(db.FileDown)
    End Function
Index.aspx 內容
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of IEnumerable (Of UpDownFileFromDBMvc.FileDown))" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    檔案列表
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>檔案列表</h2>
<ul>
    <li><%: Html.ActionLink("單一檔案上傳", "Upload")%></li>
    <li><%: Html.ActionLink("多檔案上傳", "MultiUpload")%></li>
</ul>
<table>
    <tr>
        <th>
            FileId
        </th>
        <th>
            FileName
        </th>
        <th>
            FileSize
        </th>
        <th>
            FileType
        </th>
        <th>
            FileVersion
        </th>
        <th>
            PostDate
        </th>
        <th>
            UploadDate
        </th>
        <th>
            rowguid
        </th>
    </tr>

<% For Each item In Model %>
    <% Dim currentItem = item %>
    <tr>
        <td>
            <%: Html.DisplayFor(Function(modelItem) currentItem.FileId) %>
        </td>
        <td>
            <%: Html.ActionLink(currentItem.FileName, "download", New With {.id = currentItem.FileId})%>
        </td>
        <td>
            <%: Html.DisplayFor(Function(modelItem) currentItem.FileSize) %>
        </td>
        <td>
            <%: Html.DisplayFor(Function(modelItem) currentItem.FileType) %>
        </td>
        <td>
            <%: Html.DisplayFor(Function(modelItem) currentItem.FileVersion) %>
        </td>
        <td>
            <%: Html.DisplayFor(Function(modelItem) currentItem.PostDate) %>
        </td>
        <td>
            <%: Html.DisplayFor(Function(modelItem) currentItem.UploadDate) %>
        </td>
        <td>
            <%: Html.DisplayFor(Function(modelItem) currentItem.rowguid) %>
        </td>
    </tr>
<% Next %>

</table>

</asp:Content>

要注意的有 <%: Html.ActionLink(currentItem.FileName, "download", New With {.id = currentItem.FileId})%> ,上傳後,我們希望可以直接點擊檔案名稱就可以下載檔案,所以我們把原本的DisplayFor()改寫為Html.ActionLink()。

        ''' <summary>
        ''' MVC 單一檔案上傳
        ''' </summary>
        ''' <param name="upfile">上傳檔案</param>
        ''' <param name="formData">其他表單資料</param>
        <HttpPost()>
        Function Upload(upfile As HttpPostedFileBase, formData As FormCollection) As ActionResult
            Using db As New FilesEntities
                ' 需有上傳檔案
                If upfile IsNot Nothing Then
                    ' 0 < 容量 < 4 MB
                    Dim MBSize As Integer = upfile.ContentLength / 1000 / 1000
                    If upfile.ContentLength > 0 AndAlso MBSize < 4 Then
                        Dim savePath As String = Path.Combine(Server.MapPath("~/Files/"), upfile.FileName)

                        ' 只能上傳 7z 壓縮的檔案
                        If Path.GetExtension(savePath) <> ".7z" Then
                            ModelState.AddModelError("upfile", "檔案必須由 7z 壓縮才能上傳!")
                            Return View()
                        End If

                        ' 日期需正確
                        If IsDate(formData("PostDate")) = False Then
                            ModelState.AddModelError("PostDate", "日期格式不正確!")
                            Return View()
                        End If

                        ' 版本不得空白
                        If formData("FileVersion") = "" Then
                            ModelState.AddModelError("FileVersion", "請輸入此檔案的版本!")
                            Return View()
                        End If

                        ' 檔案不存在,進行上傳儲存動作
                        If System.IO.File.Exists(savePath) = False Then

                            ' 進行資料庫確認
                            Dim FileDuplicate As FileDown = (From f In db.FileDown
                                                             Where (f.FileName = upfile.FileName)
                                                             Select f).FirstOrDefault()

                            ' 檔名未重複
                            If FileDuplicate Is Nothing Then
                                ' 儲存至Disk
                                upfile.SaveAs(savePath)

                                ' 設定檔案資訊
                                Dim file As New FileDown
                                file.FileName = upfile.FileName
                                file.FileSize = upfile.ContentLength
                                file.FileType = upfile.ContentType
                                file.PostDate = formData("PostDate")
                                file.FileVersion = formData("FileVersion")
                                file.UploadDate = Date.Now()
                                file.rowguid = Guid.NewGuid()

                                ' 將檔案資訊儲存至資料庫
                                db.FileDown.Add(file)
                                db.SaveChanges()
                            Else
                                ModelState.AddModelError("upfile", "資料庫檔案資訊未刪除!")
                                Return View()
                            End If
                        Else
                            ModelState.AddModelError("upfile", "檔案已存在!")
                            Return View()
                        End If
                    End If
                End If
            End Using

            Return RedirectToAction("Index")
        End Function

我們在專案目鍵下建立一個 Files 目錄,用來儲存上傳的檔案。這裡要注意傳入參數的前後順序,Upload.aspx 的表單順序,如果上傳檔案欄位第一個,那麼 upfile As HttpPostedFileBase 就要在第一個,反之亦然。

Upload.aspx
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Upload One File
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Upload One File</h2>

<%Using Html.BeginForm("Upload", "file", FormMethod.Post, New With {.enctype = "multipart/form-data"})%>
    <%: Html.ValidationSummary(True)%>
    File:<input id="upfile" name="upfile" type="file" value="" />
          <%: Html.ValidationMessage("upfile")%>
    <br />
    PostDate:<%: Html.TextBox("PostDate")%>
          <%: Html.ValidationMessage("PostDate")%>
    <br />
    Version:<%: Html.TextBox("FileVersion")%>
          <%: Html.ValidationMessage("FileVersion")%>
    <br />
    <input type="submit" value="Upload" />
<%End Using%>

</asp:Content>

MVC 多檔案上傳

接下來我們來看多檔案上傳。

        ''' <summary>
        ''' MVC 多檔案同時上傳
        ''' </summary>
        ''' <param name="form">表單資料</param>
        <HttpPost()>
        Function MultiUpload(form As FormCollection) As ActionResult
            ' 資料檢查,請自行設計

            Dim Msg As String = String.Empty
            For i As Integer = 0 To Request.Files.Count - 1
                Msg += Request.Files(i).FileName & " 上傳成功!<br />"
                Request.Files(i).SaveAs(Server.MapPath("~/Files/") & Request.Files(i).FileName)
            Next

            ViewBag.Msg = MvcHtmlString.Create(Msg)

            Return View()
        End Function

這裡讓我偷懶一下,檔案的檢查與資訊新增至資料庫都和Upload差不多,讓你動點手。

<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Upload Multi-Files
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Upload Multi-Files</h2>
<%: Html.ActionLink("Go back Index","Index") %>
<% Using (Html.BeginForm("MultiUpload", "File", FormMethod.Post, New With {.enctype = "multipart/form-data"}))%>
        <div class="uploadfiles">
            <p>
                <input type="file" name="files" />
            </p>
        </div>
        <p>
            <a href="#add" id="additem">Add Upload File</a>
            <br /><br />
            <input type="submit" value="Upload" />
        </p>
<% End Using%>

<%: ViewBag.Msg %>
<script type="text/javascript">
    $('#additem').live('click', function () {
        $('.uploadfiles').append($("<p><input type='file' name='files' /></p>"));
    });
</script>
</asp:Content>

重點在列下方那一段 jQeruy,讓我們重態新增要上傳資料的欄位。

MVC 檔案下載

最後的Download程式。
Function Download(id As Integer) As ActionResult
            Using db As New FilesEntities

                ' 取得檔案資訊
                Dim getfile = (From f In db.FileDown
                              Where f.FileId = id
                              Select f).FirstOrDefault()

                If getfile.FileName IsNot Nothing Then
                    Dim FilePath As String = Server.MapPath("~/Files/" & getfile.FileName)

                    ' 進行下載
                    If System.IO.File.Exists(FilePath) Then
                        Return File(FilePath, getfile.FileType, getfile.FileName)
                    End If
                Else
                    ' 回應錯誤
                    Return Content("<span style='color:red'>無法下載檔案!</span>")
                End If
            End Using

            Return RedirectToAction("Index")
        End Function

我們資料表設計裡有Guid,你也可以設計一個使用Guid來讓使用者下載的方法,這樣使用者就無法使用1,2,3,4這樣的好猜的數字來下載資料。

MVC 檔案刪除

又想偷懶了,程式給你寫。

  1. 傳入id從資料庫找到檔案名稱。
  2. 使用Path.Combine與Server.MapPath()組合出完整路徑。
  3. 使用File.Exists(路徑)判斷檔案是否存在。
  4. 存在,刪除檔案及資料庫資訊。( File.Delete(路徑) )
這樣一個可上傳、下載、刪除的簡易檔案管理程式就完成了。

參考資料

  1. ASP.NET MVC 檔案上傳下載是很方便的 
  2. ASP.NET MVC的檔案上傳與下載 
  3. ASP.NET MVC FileUpload 檔案上傳