2009年4月24日 星期五

ASP.NET無接縫傳值頁面處理後續-如何重新整理來源頁面?

問題說明:
 當我們使用了無接縫傳值撰寫模式,完成Master/Detail的編修資料後,大部份的情況都需要重新整理來源頁的頁面,才能立即顯示修正後的資料。在這種情況下要如何處理?
可能方法包含:
1.使用window.opener.location.reload();
2.呼叫來源頁的重整功能。
這兩個方法中,window.opener.location.reload();會產生是否要重整的確認視窗,而且整個網頁重新進入一次,使用上比較不經濟。第二個方法可以配合AJAX把握重點,只整理需要的頁面。
個人習慣使用第二種方法。

我的作法:
 1.在來源頁上配置一個ImageButton的Control。語法如下:
 <asp:imagebutton id="refreshBU" alternatetext="頁面重整" imageurl="~/Images/refresh.png" oncommand="refreshBU_Command" runat="server">
 2.加入一個doRefresh()的javascript function(),語法如下:
 function doRefresh() { doClickId("<%=refreshBU.ClientID %>"); }
 doClickId()在ASP.NET無接縫傳值撰寫模式中已建立。
 3.撰寫refreshBU_Command事件處理機制,可能是重新Binding GridView。
 4.彈出的頁面中加入編修或處理結束後來源頁的功能呼叫。語法如下:
 <script type="text/javascript">
 function confirmSave(){
 alert('回應資料已存檔,頁面即將關閉!');
 window.opener.doRefresh();
 window.open('', '_parent', '');
 window.close();
 }
 </script> 

2009年4月20日 星期一

一個關於ASP.NET RadioButtonList 控制元件操作上的注意事項

問題說明:
在ASP.NET的環境中操作RadioButtonList 控制元件時,如果在伺服端預設SelectedIndex時;例如設定了SelectedIndex=0,當使用者於網頁上點選第一項以外的選項時,SelectedIndexChanged的事件可以正常運作,但時回點第一項選項時發現無法啟動SelectedIndexChanged的事件。
也就是說在伺服端預設的SelectedIndex後,會導致該選項沒有SelectedIndexChanged的事件。

解決方法:
必須於網頁OnLoad或OnFocus時,使用Javascript定義預設的選項,不能在伺服端預設選項。
下面是我的作法:
window.onfocus = function() {
 var ctrl = document.getElementById("<%=RadioButtonList1.ClientID%>" + "_0");
 ctrl.checked = true;
};

2009年3月27日 星期五

網頁輸入頁面Enter鍵處理元件(KeyDownProcess Version:1.1)

function KeyDownProcess() {
//-----------------------------------------------------------
//網頁親和性輸入控制元件
//元件功能:可以讓網頁資料的輸入更親切,功能如下:
//1.按下Enter鍵自動找到下一個可輸入輸入元件
//2.按下Enter鍵自動找尋submit按鍵,如果找到則模擬Click的功能
//版本:1.1(2009.03.27)
//作者:科碩資訊有限公司
//引用本元件,請保留作者和版本資訊
//聯絡mail:cursor@cursorinfo.com.tw
//------------------------------------------------------------
var kv = 0;
var rv = false;
var isTextarea = false;
var currentId = null; //目前元件
if (document.all && typeof (document.all) == "object") {
kv = event.keyCode;
isTextarea = (event.srcElement.tagName == "TEXTAREA");
currentId = event.srcElement.id;
}
else {
kv = evt.keyCode;
isTextarea = (evt.target == "TEXTAREA");
currentId = evt.id;
}
switch (kv) {
case 13:
if (currentId.length == 0)
return false;
if (isTextarea == true) {
rv = isTextarea;
}
else {
var cts = document.all && typeof (document.all) == "object" ? document.all : document.getElementsByTagName('input');
var cid = "";
var queryBu = null;
var beginNext = false; //開始比對是否為輸入元件
var nextInput = null; //下一個輸入元件
var specialSubmitId = "logonBU"; //指定特例的submit id
var exceptionSubmitId = "waitting"; //指定例外的submit Id
for (ii = 0; ii < cts.length; ii++) {
if (cts[ii].id == currentId) {
beginNext = true;
continue;
}
if (beginNext == true && (cts[ii].id.indexOf(specialSubmitId) > -1 || (cts[ii].type == "submit" && cts[ii].id.indexOf(exceptionSubmitId) == -1))) {
queryBu = cts[ii]; //找到submit元件
break;
}
else if (beginNext == true && (cts[ii].type == "text" || cts[ii].type == "textarea" || cts[ii].type == "password") && cts[ii].readOnly == false && cts[ii].style.display != "none") {
nextInput = cts[ii]; //找到下一個文字輸入元件
break;
}
}
if (null != queryBu) {
setTimeout("doClickId('" + queryBu.id + "');", 100);
rv = false;
}
else if (null != nextInput) {
try {
nextInput.focus();
} catch (Error) { return true; }
rv = false;
}
}
break;
default:
rv = true;
break;
}
return rv;
}

//實做模擬Click的功能
function doClickId(source) {
var o=document.getElementById(source);
if (document.all && typeof (document.all) == "object") //IE
o.click();
else {
var e = document.createEvent('mouseEvent');
e.initEvent('click', false, false);
o.dispatchEvent(e);
}
}

2009年3月16日 星期一

ADSI技術文章-使用WinNT Provider取得User的Groups

public Dictionary GetWinNtUserGroups(string userName, string uName, string pwd)
{
Dictionary rv = new Dictionary();
string adsPath = string.Format("WinNT://{0}/{1},user", Environment.MachineName, userName);
if (DirectoryEntry.Exists(adsPath) == true)
{
DirectoryEntry user = new DirectoryEntry(adsPath, uName, pwd);
IADsGroup ig;
//叫用 Group 的 Members
object groups = user.Invoke("Groups", null);
DirectoryEntry gEntry;
foreach (object go in (IEnumerable)groups)
{
gEntry = new DirectoryEntry(go);
if (gEntry.SchemaClassName.ToLower() == "group")
{
ig = (IADsGroup)gEntry.NativeObject;
rv.Add(ig.Name, ig.Description);
}
}
}
return rv;
}

ADSI技術文章-使用WinNT Provider取得User的Groups

問題說明:
如果我們想使用WinNT Provider,取得user的群組清單,應該如何做呢?
下面範例會傳回一組群組名稱和描述的Dictionary資料:

public Dictionary GetWinNtUserGroups(string userName, string uName, string pwd)
{
Dictionary rv = new Dictionary();
string adsPath = string.Format("WinNT://{0}/{1},user", Environment.MachineName, userName);
if (DirectoryEntry.Exists(adsPath) == true)
{
DirectoryEntry user = new DirectoryEntry(adsPath, uName, pwd);
IADsGroup ig;
//叫用 User 的 Groups
object groups = user.Invoke("Groups", null);
DirectoryEntry gEntry;
foreach (object go in (IEnumerable)groups)
{
gEntry = new DirectoryEntry(go);
if (gEntry.SchemaClassName.ToLower() == "group")
{
ig = (IADsGroup)gEntry.NativeObject;
rv.Add(ig.Name, ig.Description);
}
}
}
return rv;
}
*使用IADsGroup的COM介面,可以輕鬆取得group的屬性。
*使用IADsGroup的COM介面,須參考ActiveDs.dll。

2009年3月15日 星期日

如何利用Web 服務描述語言工具(Wsdl.exe)產生Web Service的類別?

問題說明:
.NET Framework 提供了Web 服務描述語言工具Wsdl.exe,最主要的用途是: 從WSDL 合約檔案、XSD 結構描述 (Schema) 和 .discomap 探索文件產生 XML Web Service 和 XML Web Service 用戶端的程式碼。其中產生XML Web Service 用戶端的程式碼,就是只產生Web Service的用戶端類別,做為應用程式直接引用的來源。
使用 Wsdl.exe 建立 Proxy 類別時,請參閱Microsoft MSDN說明。
網址:Web 服務描述語言工具 (Wsdl.exe)

Wsdl.exe存放位址:C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin

建立Web Service Proxy類別,最直接的方法如下:
1.假設目前有一個Web Service的網址為:http://ws.interfax.net/admin.asmx
2.使用下列語法可以產生Web Service Proxy類別,檔名為admin.cs:
 wsdl /out:admin.cs http://ws.interfax.net/admin.asmx?wsdl
3.將該類別加入應用程式專案,就可以直接呼叫Web Service的Method 或Properties。應用程式不必另行加入Web參考。

另外,您可以使用 Web 服務探索工具 (Disco.exe) 來取得 XML Web Service 的探索文件。由這個工具所產生的 .discomap、.disco、.wsdl 和 .xsd 檔案可以用作 Wsdl.exe 的輸入。

2009年3月13日 星期五

ADSI相關雜記

*Windows 2008 Server安裝Active Directory時,提供AdsiEdit.msc服務。使用該服務可以完整瀏覽與管理,AD的物件與物件屬性。

*Windows 2003 server使用ADSI WinNT Provider 新增、異動物件時,須設定:
同步處理目錄服務之帳號(本機安全性設定-使用者權利指派-同步處理目錄服務的資料)