2009年11月27日 星期五

存取遠端資料庫伺服器的方法

三種方法可擇一使用

1. 使用SQL Server Enterprise Manager工具


選擇某一SQL Server --> 安全性 --> 連結伺服器 --> 新增連結伺服器  在【一般】頁籤中的連結的伺服器欄位中輸入欲連結伺服器的網路名稱全名。
顯示畫面如下:



在【安全性】頁籤中,選擇【使用下列安全性條件進行連線】輸入帳號及密碼。
顯示畫面如下:



2. 在QUERY ANALYZER中輸入


EXEC sp_addlinkedserver ‘xxx.xxx.xxx.xxx’,N’SQLServer的名稱’

EXEC sp_addlinkedsrvlogin ‘xxx.xxx.xxx.xxx’,’false’,NULL,’使用者帳號’,’密碼’

註: 其中紅色字體的N就直接輸入N 代表後面的字是Unicode

3. 直接在SQL指令中加入遠端伺服器連結資訊


以下範例查詢cydc.cyu.edu.tw資料庫伺服器中person資料庫的dbo所擁有的baperson資料表

select *


from opendatasource('sqloledb','data source=cydc.cyu.edu.tw;user id=帳號;password=密碼').person.dbo.baperson

4. 不同使用方法的差異:


若使用上述1及2的方式只需事先於該SQL Server中執行一次註冊動作,往後執行SQL 指令時可直接使用以下的方法連結到遠端資料庫:

select *


from [cydc.cyu.edu.tw].person.dbo.baperson

若使用第3種方法的話,則只需於每次執行SQL 指令時加入相關的連結資訊即可,不需事先執行1及2的前置動作。

2009年11月26日 星期四

開啟沒有功能列的新視窗

Dim javascript As String
javascript = "window.open('aaa.aspx','','left=150,top=150,width=600,height=600,toolbar=0,resizable=0');"
Page.ClientScript.RegisterClientScriptBlock(GetType(Page), Me.ClientID, javascript, True)
Dim javascript As String
javascript = " "
Response.Write(javascript)

gridview列: 數位、貨幣和日期 顯示格式

形式 語法 結果 注釋


數字 {0:N2} 12.36

數字 {0:N0} 13

貨幣 {0:c2} $12.36

貨幣 {0:c4} $12.3656

貨幣 "¥{0:N2}" ¥12.36

科學計數法 {0:E3} 1.23E+001

百分數 {0:P} 12.25% P and p present the same.

日期 {0:D} 2006年11月25日

日期 {0:d} 2006-11-25

日期 {0:f} 2006年11月25日 10:30

日期 {0:F} 2006年11月25日 10:30:00

日期 {0:s} 2006-11-26 10:30:00

時間 {0:T} 10:30:00

在設置gridview等資料綁定控制項的模版列時,總要設置顯示的格式,這裏是我查詢一些資料後統計出來的。


還有一個常規的選項是用資料庫中默認的格式顯示。



四捨五入保留兩位小數:

double dValue = 0.2356;

double result = System.Math.Round(dValue,2);



直接用 i.ToString("0.00")



格式化

日期:

ToString("yyyy-MM-dd")

返回2004-9-7

時間:

ataFormatString="{0: HH:mm:ss}"

(:) 時間分隔符號。在某些區域設置中,可以使用其他字元表示時間分隔符號。時間分隔符號在格式化時間值時分隔小時、分鐘和秒。格式化輸出中用作時間分隔符號的實際字元由系統的 LocaleID 值確定。

(/) 日期分隔符號。在某些區域設置中,可以使用其他字元表示日期分隔符號。日期分隔符號在格式化日期值時分隔日、月和年。格式化輸出中用作日期分隔符號的實際字元由您的區域設置確定。

(%) 用於表明不論尾隨什麼字母,隨後字元都應該以單字母格式讀取。也用於表明單字母格式應以用戶定義格式讀取。有關詳細資訊,請參見下面的內容。

d 將日顯示為不帶前導零的數字(如 1)。如果這是用戶定義的數位格式中的唯一字元,請使用 %d。

dd 將日顯示為帶前導零的數字(如 01)。

ddd 將日顯示為縮寫形式(例如 Sun)。

dddd 將日顯示為全名(例如 Sunday)。

M 將月份顯示為不帶前導零的數字(如一月表示為 1)。如果這是用戶定義的數位格式中的唯一字元,請使用 %M。

MM 將月份顯示為帶前導零的數字(例如 01/12/01)。

MMM 將月份顯示為縮寫形式(例如 Jan)。

MMMM 將月份顯示為完整月份名(例如 January)。

gg 顯示時代/紀元字串(例如 A.D.)

h 使用 12 小時制將小時顯示為不帶前導零的數字(例如 1:15:15 PM)。如果這是用戶定義的數位格式中的唯一字元,請使用 %h。

hh 使用 12 小時制將小時顯示為帶前導零的數字(例如 01:15:15 PM)。

H 使用 24 小時制將小時顯示為不帶前導零的數字(例如 1:15:15)。如果這是用戶定義的數位格式中的唯一字元,請使用 %H。

HH 使用 24 小時制將小時顯示為帶前導零的數字(例如 01:15:15)。

m 將分鐘顯示為不帶前導零的數字(例如 12:1:15)。如果這是用戶定義的數位格式中的唯一字元,請使用 %m。

mm 將分鐘顯示為帶前導零的數字(例如 12:01:15)。

s 將秒顯示為不帶前導零的數字(例如 12:15:5)。如果這是用戶定義的數位格式中的唯一字元,請使用 %s。

ss 將秒顯示為帶前導零的數字(例如 12:15:05)。

F 顯示秒的小數部分。例如,ff 將精確顯示到百分之一秒,而 ffff 將精確顯示到萬分之一秒。用戶定義格式中最多可使用七個 f 符號。如果這是用戶定義的數位格式中的唯一字元,請使用 %f。

T 使用 12 小時制,並對中午之前的任一小時顯示大寫的 A,對中午到 11:59 P.M 之間的任一小時顯示大寫的 P。如果這是用戶定義的數位格式中的唯一字元,請使用 %t。

tt 使用 12 小時制,並對中午之前任一小時顯示大寫的 AM;對中午到 11:59 P.M 之間的任一小時顯示大寫的 PM。

y 將年份 (0-9) 顯示為不帶前導零的數字。如果這是用戶定義的數位格式中的唯一字元,請使用 %y。

yy 以帶前導零的兩位元數位格式顯示年份(如果適用)。

yyy 以四位元數位格式顯示年份。

yyyy 以四位元數位格式顯示年份。

z 顯示不帶前導零的時區偏移量(如 -8)。如果這是用戶定義的數位格式中的唯一字元,請使用 %z。

zz 顯示帶前導零的時區偏移量(例如 -08)

zzz 顯示完整的時區偏移量(例如 -08:00)

讀取Excel檔資料存到DB中

string xlsFullName = FileUpload1.PostedFile.FileName;
string FileName = FileUpload1.PostedFile.FileName.Substring(FileUpload1.PostedFile.FileName.LastIndexOf("\\") + 1, FileUpload1.PostedFile.FileName.Length - FileUpload1.PostedFile.FileName.LastIndexOf("\\") - 1);

//讀取路徑給Step2
Session["xlsFullName"] = xlsFullName;
Session["FileName"] = FileName;
//Session()
//HDR=Yes 代表 EXCEL 第一列為欄位名稱 IMEX=1 為將混合型態的資料一律以文字型態顯示
// string OleConStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + xlsFullName + "; Extended Properties= \"Excel 8.0;HDR=NO \" ";
string OleConStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + xlsFullName + ";Extended Properties='Excel 8.0;HDR=NO;'";
//string OleConStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + xlsFullName + ";Extended Properties=Excel 8.0;";
DataSet ds = new DataSet();
OleDbConnection OleCn = new OleDbConnection(OleConStr);
string strSQL = @"SELECT * FROM [Sheet1$]";
try
{
OleCn.Open();
OleDbDataAdapter oledbda = new OleDbDataAdapter(strSQL, OleCn);
oledbda.Fill(ds, "NewExcel");
//Table給新欄名
ds.Tables["NewExcel"].Columns[0].ColumnName = "C1";
ds.Tables["NewExcel"].Columns[1].ColumnName = "C2";
ds.Tables["NewExcel"].Columns[2].ColumnName = "C3";
ds.Tables["NewExcel"].Columns[3].ColumnName = "C4";
ds.Tables["NewExcel"].Columns[4].ColumnName = "C5";
ds.Tables["NewExcel"].Columns[5].ColumnName = "C6";
ds.Tables["NewExcel"].Columns[6].ColumnName = "C7";
ds.Tables["NewExcel"].Columns[7].ColumnName = "C8";

GridView1.DataSource = ds.Tables["NewExcel"];
GridView1.DataBind();
}
catch
{
String scriptString = @"

";
this.RegisterStartupScript("s", scriptString);
return;
}
}
}

其他參考資料:
 1. HOW TO:使用 ADO.NET 擷取與修改利用 Visual Basic .NET 之 Excel 活頁簿中的記錄
http://support.microsoft.com/kb/316934/zh-tw
2.ExcelADO 示範使用 ADO 在 Excel 活頁簿讀取和寫入資料的方法
http://support.microsoft.com/kb/278973/ZH-TW/
參考ExcelADO.exe檔
問題:
時機:使用者可能回自行要連接資料庫,但是ConnectionString太複雜不好撰寫
方法:事實上微軟已經把這個對話盒包裝起來,
包含:
1.建立ConnectionString
2.開啟*.udl檔案,讀入ConnectionString
3.寫入*.udl檔案,用已知的ConnectionString,幫你產生*.udl檔案

答案:
實做
1. 先加入參考->COM
C:\Program Files\Common Files\System\OLE DB\oledb32.dll

說明:這個檔案oledb32.dll,就是幫我們操作ConnectionString的物件,事實上早已存在(舊的OleDB物件),並不是.NET物件,之後VS.NET會幫我們產生一個For.NET的檔案,這是用來呼叫oledb32的.NET DLL檔


2. 再加入參考->.NET
adodb (C:\Program Files\Microsoft.NET\Primary Interop Assemblies\adodb.dll)
說明:因為oledb32是要利用ADO Object(不能利用ADO.net)來承接所產生出來的ConnectionString,所以我們必須要建立ADO物件
程式:
///
/// 啟動ConnectionString對話盒
///

/// 預設的ConnectionString
/// 回傳ConnectionString
public string OpenConnectionStringDialog(string vDefaultConnectionString)
{
MSDASC.DataLinksClass DataLinkObj = new MSDASC.DataLinksClass();
ADODB.ConnectionClass ConnObj = new ADODB.ConnectionClass();
ConnObj.ConnectionString = vDefaultConnectionString;
object TempConnObj = (object)ConnObj;
DataLinkObj.PromptEdit(ref TempConnObj);
return ConnObj.ConnectionString;
}

3. 說明:會傳入一個預設的ConnectionString可預帶之前的設定
備註:發布時一定要把oledb32.dll和Interop.MSDASC.dll一起發布給Client端

動態畫2D圖

Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Drawing2D
Imports System.Drawing.Text
Imports System.Data.SqlClient
Imports System.Web.Configuration

Partial Class _Default

Inherits System.Web.UI.Page
Private _Width As Integer = 600
Private _Height As Integer = 600

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

Dim BitmapImage As New Bitmap(_Width, _Height, PixelFormat.Format32bppArgb)
Dim Canvas As Graphics = Graphics.FromImage(BitmapImage)
' 好了,現在我們取得 Graphics,在這張畫布畫圖,相當於畫在 Bitmap 上
' 填入漸層藍色當背景
Dim ClientArea As New Rectangle(New Point(0, 0), New Size(_Width, _Height))
Dim BlueGradientBrush As New LinearGradientBrush(New Point(0, 0), _
New Point(0, _Height), Color.White, Color.White)
Canvas.FillRectangle(BlueGradientBrush, ClientArea)
' 畫出邊框
Dim BluePen As New Pen(Color.Black, 2)
Canvas.DrawRectangle(BluePen, ClientArea)
Graphics_Loop(Canvas, "888888888888888", 5, 10, 100, 20)
Graphics_Loop(Canvas, "99999", 5, 35, 100, 20)

' 以標楷體 18 點斜體字樣秀出文字
'Dim SF As New StringFormat(StringFormatFlags.NoWrap Or _
' StringFormatFlags.NoFontFallback)
'SF.LineAlignment = StringAlignment.Near
'SF.Alignment = StringAlignment.Center
'Dim F As Font = New Font("標楷體", 18, FontStyle.Italic)
'ClientArea.Offset(0, 4)
'Canvas.DrawString(ContentString, F, Brushes.Black, _
' CType(ClientArea, RectangleF), SF)
'ClientArea.Offset(0, -4)

' 再裝飾一段底線文字
'Canvas.FillRectangle(Brushes.Black, 0, 30, _Width, 10)
'SF.LineAlignment = StringAlignment.Far
'SF.Alignment = StringAlignment.Center
'F = New Font("Arial", 8, FontStyle.Italic)
'Canvas.DrawString("Anti-phishing with Sign-in Seal", F, _
' Brushes.White, CType(ClientArea, RectangleF), SF)

' 輸出圖片到 Client 端
Response.Clear()
Response.ContentType = "image/jpeg"
BitmapImage.Save(Response.OutputStream, ImageFormat.Jpeg)
Response.End()
End Sub

Function Graphics_Loop(ByVal Canvas As Graphics, ByVal Txt As String, ByVal xv As Integer, ByVal yv As Integer, ByVal wv As Integer, ByVal hv As Integer)
Dim ClientArea As New Rectangle(New Point(xv, yv), New Size(wv, hv))
Dim BluePen As New Pen(Color.Black, 1)
Canvas.DrawRectangle(BluePen, ClientArea)
Dim SF As New StringFormat(StringFormatFlags.NoWrap Or _
StringFormatFlags.NoFontFallback)
SF.LineAlignment = StringAlignment.Near
SF.Alignment = StringAlignment.Center
Dim F As Font = New Font("標楷體", 12, FontStyle.Bold)
ClientArea.Offset(0, 4)
Canvas.DrawString(txt, F, Brushes.Black, _
CType(ClientArea, RectangleF), SF)
ClientArea.Offset(0, -4)
End Function
End Class

把aspx程式預先編譯的方法

指令
aspnet_compiler -v std -p d:\aspx\整個網頁目錄 d:\產生目標目錄

利用 BasePage 實作表單權限控管

來源:ASP.NET魔法學院

連結:http://itgroup.blueshop.com.tw/jeff377/blog?n=convew&i=2106

十幾行程式碼搞定 Master-Detail GridView(內含子 GridView)

來源:ASP.NET魔法學院
連結:http://itgroup.blueshop.com.tw/jeff377/blog?n=convew&i=2111

擴展 CommandField 類別 - 刪除提示訊息含欄位值

來源 : ASP.NET 魔法學院
在之前的「擴展 CommandField 類別 - 刪除提示訊息」文章中實作了 TBCommandField 類別,設定 DeleteConfirmMessage 屬性可以輕易設定刪除提示訊息。

這篇文章針對 TBCommandField 類別做進一步的擴展,我們希望在刪除訊息中可以加入指定的欄位值,讓使用者明確知道刪除的資料,例如刪除某個產品資料時,可以顯示這個產品的名稱在提示訊息中。

針對這個需求,在 TBCommandField 類別新增一個 DataField 屬性,設定刪除提示訊息中顯示欄位值的資料欄位名稱。因為要取得繫結的欄位資料,所以在 SetDeleteButton 私有方法中,設定刪除鈕 DataBinding 事件處理函式為 OnDataBindField,當 GridView 做 DataBind 時,就會引發子控制項的 DataBinding 事件,此時就會執行 OnDataBindField 方法,這時可以取得繫結的資料的 DataRowView,然後就可以從 DataRowView 中取得 DateField 的欄位值。

實作程式碼如下

Imports System
2 Imports System.Collections.Generic
3 Imports System.ComponentModel
4 Imports System.Text
5 Imports System.Web
6 Imports System.Web.UI
7 Imports System.Web.UI.WebControls
8
9
10 Public Class TBCommandField
11 Inherits CommandField
12
13 Private FDeleteConfirmMessage As String = String.Empty
14 Private FDataField As String = String.Empty
15
16 '''
17 ''' 刪除提示訊息。
18 '''

19 Public Property DeleteConfirmMessage() As String
20 Get
21 Return FDeleteConfirmMessage
22 End Get
23 Set(ByVal value As String)
24 FDeleteConfirmMessage = value
25 End Set
26 End Property
27
28 '''
29 ''' 刪除提示訊息顯示欄位值的資料欄位名稱。
30 '''

31 Public Property DataField() As String
32 Get
33 Return FDataField
34 End Get
35 Set(ByVal value As String)
36 FDataField = value
37 End Set
38 End Property
39
40 '''
41 ''' 初始化儲存格。
42 '''

43 '''
要初始化的儲存格。44 '''
儲存格類型。45 '''
儲存格狀態。46 '''
資料列之以零起始的索引。47 '''
48 Public Overrides Sub InitializeCell(ByVal cell As DataControlFieldCell, ByVal cellType As DataControlCellType, ByVal rowState As DataControlRowState, ByVal rowIndex As Integer)
49 MyBase.InitializeCell(cell, cellType, rowState, rowIndex)
50 If Me.ShowDeleteButton AndAlso Me.Visible AndAlso Me.DeleteConfirmMessage <> String.Empty Then
51 SetDeleteButton(cell)
52 End If
53 End Sub
54
55 '''
56 ''' 建立新的 TBCommandField 物件。
57 '''

58 Protected Overrides Function CreateField() As DataControlField
59 Return New TBCommandField()
60 End Function
61
62 '''
63 ''' 將目前 TBCommandField 物件的屬性複製到指定之 DataControlField 物件。
64 '''

65 '''
目的 DataControlField 物件。66 Protected Overrides Sub CopyProperties(ByVal NewField As DataControlField)
67 Dim oNewField As TBCommandField
68
69 oNewField = DirectCast(NewField, TBCommandField)
70 oNewField.DeleteConfirmMessage = Me.DeleteConfirmMessage
71 oNewField.DataField = Me.DataField
72 MyBase.CopyProperties(NewField)
73 End Sub
74
75 '''
76 ''' 設定刪除鈕。
77 '''

78 '''
儲存格。79 Private Sub SetDeleteButton(ByVal Cell As DataControlFieldCell)
80 Dim oControl As Control
81
82 For Each oControl In Cell.Controls
83 If TypeOf (oControl) Is IButtonControl Then
84 If DirectCast(oControl, IButtonControl).CommandName = "Delete" Then
85 '設定刪除鈕的 DataBinding 事件處理函式
86 AddHandler oControl.DataBinding, New EventHandler(AddressOf Me.OnDataBindField)
87 Exit Sub
88 End If
89 End If
90 Next
91 End Sub
92
93 '''
94 ''' 將欄位值繫結至 TBCommandField 物件。
95 '''

96 Protected Overridable Sub OnDataBindField(ByVal sender As Object, ByVal e As EventArgs)
97 Dim oControl As Control
98 Dim oDataItem As Object
99 Dim oDataRowView As Data.DataRowView
100 Dim sScript As String
101 Dim sMessage As String
102
103 oControl = DirectCast(sender, Control)
104
105 If Me.DataField <> String.Empty Then
106 '處理訊息中的欄位值
107 oDataItem = DataBinder.GetDataItem(oControl.NamingContainer)
108 oDataRowView = CType(oDataItem, Data.DataRowView)
109 sMessage = String.Format(Me.DeleteConfirmMessage, oDataRowView.Item(Me.DataField).ToString())
110 Else
111 sMessage = Me.DeleteConfirmMessage
112 End If
113
114 sMessage = Strings.Replace(sMessage, "'", "\'") '處理單引號
115 sScript = "if (confirm('" & sMessage & "')==false) {return false;}"
116 DirectCast(oControl, WebControl).Attributes("onclick") = sScript
117 End Sub
118
119 End Class

使用時在 aspx 程式碼中設定其 DeleteConfirmMessage 及 DateField 屬性就在刪除提示訊息加入欄位值。其中 DeleteConfirmMessage="確定刪除 {0} 這筆資料嗎?" 中的 {0} 就是 ProductName 欄位值顯示的位置。


1 >
view plain |



如何讓自己開發的.Net 元件顯示在.Net 元件參考的視窗Tab中 ?

目的:
讓自己開發的.Net 元件顯示在.Net 元件參考的視窗Tab中。

作者:chsteven
語言:
步驟:
各位要顯示在.Net Component參考視窗的技巧,重點在於要在Windows Registry中加上一個機碼,而機碼位置需新增於底下路徑:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\[您自己的機碼名稱]

然後在「預設值」這個值名稱中新增您的Component的實體目錄路徑。

舉例來說,我有一個AA.dll,路徑位於D:\Component\Test\AA.dll
所以我可以做以下動作:

1. 新增機碼
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\myTest

2. "預設值"的值新增為:
D:\Component\Test\

如此即可。
此外, .Net提供的安裝部署程式可以幫各位登錄Registry, 所以實際上在部署元件時, 可以用這個工具來協助。

如何避免報表程式被電腦中其他的作業中斷?

問題:
在跑一個很大的報表時,常會被電腦中其他的作業中斷,如何避免?

答案:
按「Ctrl-Alt-Del」叫出「Task Manager」,切換到「Processes」在「crw32.exe」上按下滑鼠右鍵選擇「Set Prority」à「High」。

如何跨欄合併DataGrid標頭欄位?

語言:Visual C# .NET
步驟:
1. 請試著在 DataGrid 物件的 ItemCreate 事件中加入以下程式碼
private void DataGrid1_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e) {

if ( e.Item.ItemType == ListItemType.Header ) {

TableCellCollection tcl = e.Item.Cells;

tcl.Clear();

tcl.Add( new TableHeaderCell() );

tcl[0].RowSpan = 2;

tcl[0].Text = "資料項目";



tcl.Add( new TableHeaderCell() );

tcl[1].ColumnSpan = 2;

tcl[1].Text = "會計科目借貸";

}

}

如何部署Crystal Report ?

目的:
使用安裝專案,部署Crystal Report。

作者:brian_wang
語言:
步驟:
照一般建立安裝專案,加入合併模組:

(1)regwiz.msm
(2)Managed_cht.msm
(3)managed.msm
(4)Database_Access.msm
(5)Database_Access_cht.msm
(6)dotnetfxredist_x86_cht.msm
其中(3)(6)項在建立完專案時自動加入到偵測到的相依性其餘需手動加入,在第(1)項的屬性中需設定license key(在屬性視窗中可找到) 。

license key( xxxxx-xxxxxxx-xxxxxxx)在說明中最後一個選項(關於 microsoft....)可以找到。
若是報表連結時使用到DataSet ,則須另外加入 VC_CRT.msm 及VC_STL.msm 兩個項目。且需先在檔案系統中增加系統資料夾 再將VC_CRT.msm 及VC_STL.msm 兩個項目的Module Retargetable Folder的屬性設為系統資料夾,接下來便開始建置...........

如何設計動態的Top N報表?

問題:
如何設計動態的Top N報表?

答案:
用Crystal Reports 9的「Add Command」新功能。

1. 撰寫一個Command其中用一個參數來控制要選出前幾個(N)群組。

Access版的SQL Command

SELECT TOP {?N} `Customer`.`Country`, SUM(`Customer`.`Last Year's Sales`) AS Sum_Last_Years_Sales

FROM `Customer` `Customer`

GROUP BY `Customer`.`Country`

ORDER BY SUM(`Customer`.`Last Year's Sales`) DESC



SQL Server版的SQL Command

SELECT TOP {?N} SUM("CUSTOMER"."Last Year's Sales")AS Sum_Last_Years_Sales,"CUSTOMER"."COUNTRY"

FROM "Xtreme"."dbo"."CUSTOMER" "CUSTOMER"

GROUP BY "CUSTOMER"."COUNTRY"

ORDER BY SUM("CUSTOMER"."Last Year's Sales") DESC

2. 同樣在「Add Command」裡加入一個Paramenter:名稱為N、型別為Number。

3. 把「Sum_Last_Years_Sales」及「COUNTRY」欄位放入「Details」區段。

重新整理報表。便可根據使用者輸入的數字,動態顯示前N大群組。

如何取得OS登入系統帳號

目的:
在Windows表單程式中取得登入作業系統帳號。

語言:C#
步驟:
1. 引用System.Security.Principal命名空間

using System.Security.Principal;

2. 加入以下程式碼:

WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());

3. 取得帳號:

wp.Identity.Name

如何取得自己的機器IP(非127.0.0.1)

目的:
取得自己的機器IP(非127.0.0.1)

語言:任何.NET語言
步驟:
如果是 client 的 IP,那麼可以用 Request.ServerVariables[ "REMOTE_ADDR" ] 來取得。如果是 server 的 IP,那麼可以用 Request.ServerVariables[ "LOCAL_ADDR" ] 來取得。

對了, 請不要用 http://localhost/xxx/xxx.aspx 的方式來瀏覽,因為 localhost 在 hosts table 裡的 IP 預設就是 127.0.0.1,看到的結果會不正確哦!

如何抓取Client的MAC(網卡的號碼)?

目的:
抓取Client的MAC(網卡的號碼)

語言:Visual C#.NET
步驟:
1. 使用以下範例程式碼
ManagementObjectSearcher query =new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration") ;
ManagementObjectCollection queryCollection = query.Get();
foreach( ManagementObject mo in queryCollection )
{
if(mo["IPEnabled"].ToString() == "True")
MessageBox.Show(mo["MacAddress"].ToString());
}
有幾張網卡就會跑幾次,不過要確定該網卡有啟動喔,沒啟動抓不到。

如何在Visual Studio 除錯Client-Side Script

目的:
設定Visual Studio.NET工具,以利用它的除錯工具,對Client-Side Script進行單步除錯、設定中斷點,及查看變數。

作者:Adams
語言:
步驟:
1. 在 Internet Explorer, 將 Disable script debugging check box (停止指令碼偵錯)這個進階選項勾勾拿掉

2. 在 Visual Studio .NET,從選單選取Debug Processes ,將其貼附到IExplore.exe,在Running Document window,選取要除錯的.aspx

3. 在 Visual Studio .NET, 設定中斷點在妳要除錯的 client-side code

4. 在 Internet Explorer 按下 sumbit 測試

資料庫連線方式

web.config
〈appSettings〉
〈add key="cnEForm" value="server=xx.xx.xx.xx;uid=xx;Password=xx;database=xx"/〉
〈add key="cnEForm1" value="server=xx.xx.xx.xx;uid=xx;Password=xx;database=xx"/〉
〈add key="cnEForm2" value="server=xx.xx.xx.xx;uid=xx;Password=xx;database=xx"/〉
〈/appSettings〉

----程式內使用方式
Public EFormCommand As SqlCommand = New SqlCommand
Dim strConn As String = ConfigurationSettings.AppSettings("cnEForm")
Dim EFormConn = New SqlConnection(strConn)
Public AccReader As SqlDataReader
strSQL = "select BANAME,MailId,JodeCode from person..BAPERSON where baidno=" & MyFunctions.qo(IDNO)
EFormCommand = New SqlCommand(strSQL, EFormConn)
EFormConn.Open()

將資料匯出到Excel或Word

做法一:
先在專案的參考中加入Microsoft Excel 9.0 Object Library 或 Microsoft Word 9.0 Object Library COM元件(版本依安裝的Office版本而有所不同)

注意事項:
1.執行程式時要先將Office光碟片放到光碟機內,系統可能會自動安裝某些元件
2.若執行過程發生錯誤,Excel或Word會卡在記憶體內(用工作管理員查看),如果無法將之強制"結束",就必須重新開機。

Excel 程式部分:

Dim oE As New Excel.ApplicationClass
Dim oWB As Excel.Workbook
Dim oWS As Excel.Worksheet

'oE.Workbooks.Open(Server.MapPath("Book1.xls")) '使用開啟舊檔

oWB = oE.Workbooks.Add '開新檔案

oE.DisplayAlerts = False
oWS = CType(oWB.Worksheets.Item("Sheet1"), Excel.Worksheet) '取得Sheet1
oWS.Range("A1:D5").Value = "Test" '寫入資料到儲存格

oWS.SaveAs(Server.MapPath("Book2.xls")) '另存新檔

oWS = Nothing

oWB.Close()
oWB = Nothing

oE.Quit()
oE = Nothing

Word程式部分:

Dim oW As New Word.ApplicationClass
Dim oD As Word.Document

oD = oW.Documents.Open(Server.MapPath("Doc1.doc")) '開啟舊檔

oW.Selection.TypeText("測試文字測試文字測試文字測試文字測試文字") '寫入資料

oD.SaveAs(FileName:=Server.MapPath("test.doc")) '另存新檔

oD.Close()
oD = Nothing

oW.Quit()
oW = Nothing


做法二:
Response.ContentType = "application/vnd.ms-excel;charset=big5" ‘execl
Response.AppendHeader("content-disposition", "attachment; filename=aaa.xls")


Response.ContentType = "application/msword" ‘word
Response.AppendHeader("content-disposition", "attachment; filename=aaa.doc")


做法三:
Response.AppendHeader("Content-Disposition", "attachment;filename=DormitorySchedule.xls")
Response.ContentEncoding = System.Text.Encoding.GetEncoding("big5")
Response.ContentType = "application/ms-excel"

Dim oStringWriter As System.IO.StringWriter
oStringWriter = New IO.StringWriter

Dim oHtmlTextWriter As System.Web.UI.Html32TextWriter
oHtmlTextWriter = New Html32TextWriter(oStringWriter)

DataGrid2.RenderControl(oHtmlTextWriter)
Response.Write(oStringWriter.ToString())
Response.End()


Response.AppendHeader("Content-Disposition", "attachment;filename=SpendItem.xls")
Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8")
Response.ContentType = "application/ms-excel"

Dim oStringWriter As New System.IO.StringWriter
Dim oHtmlTextWriter As New System.Web.UI.HtmlTextWriter(oStringWriter)
Me.dgmaster.RenderControl(oHtmlTextWriter)

Response.Write(oStringWriter.ToString())
Response.End()


e.Item.Cells(2).Attributes.Add("style", "vnd.ms-excel.numberformat:@")

按下按鈕後,出現confirm視窗

Function PopConfirm(ByVal Msg3Show As String) As Boolean ''''Pop-up a message dialogue
Response.Write(''<'' + ''Script language=''VBScript''>'' + Chr(13))
Response.Write(''Confirm'''' + Msg3Show + '' '',, ''刪除後將無法復原,請檢查後再動作'' '')
Response.Write('''')
End Function

Private Sub DataGrid1_DeleteCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.DeleteCommand
If PopConfirm(''你確定要刪除這筆資料嗎?'') Then
processing 1
else
processing 2
End If
End Sub

呼叫Stored Procedure的方法

呼叫的方法:
get_course(btime1, etime1, smtr1, teacher_name1)

在GET_COURSE裡面就寫下面這一段就可以讀到STOREDPROCEDURE的內容了
我在WEBFORM中有加了一個SQLDATAADAPTER,然後在屬性設定中就指定要用那個STOREDPROCEDURE了
還有裡面要用那個CONNECTION,所以我在程式裡只要寫傳的參數內容即可

cmdsql.SelectCommand.Parameters("@btime").Value = btime
cmdsql.SelectCommand.Parameters("@etime").Value = etime
cmdsql.SelectCommand.Parameters("@smtr").Value = smtr
cmdsql.SelectCommand.Parameters("@teacher_name").Value = teacher_name
cmdsql.SelectCommand.Parameters("@return_value").Direction = ParameterDirection.ReturnValue
conn2.Close()
conn2.Open()
cmdsql.SelectCommand.ExecuteNonQuery()
Dim ds As DataSet = New DataSet()
ds.Tables.Add(cmdsql.SelectCommand.Parameters("@return_value").Offset)
cmdsql.Fill(ds, "coursedata")
DataGrid1.DataSource = ds.Tables("coursedata").DefaultView
DataGrid1.DataBind()

ASP語法速查表

Abs(數值)
絕對值。一個數字的絕對值是它的正值。空字串(null)的絕對值,也是空字串。未初始化的變數,其絕對為0
ex.例子:ABS(-2000) 結果:2000

Array(以逗點分隔的陣列元素)
Array函數傳回陣列元素的值。
ex.A=Array(1,2,3)
B=A(2)
結果:2
說明:變數B為A陣列的第二個元素的值。

Asc(字串)
將字串的第一字母轉換成ANSI(美國國家標準符號)字碼。
ex.Asc(〞Internet〞)
結果:73
說明:顯示第一字母I的ANSI字碼。

CBool(運算式)
轉換成布林邏輯值變數型態(True 或 False)
ex.例子:CBool(1+2)
結果:True

CDate(日期運算式)
換成日期變數型態。可先使用IsDate函數判斷是否可以轉換成日期。
ex.CDate(now( )+2)
結果:2000/5/28 10:30:59

CDbl(運算式)
轉換成DOUBLE變數型態。

Chr(ANSI字碼)
將ASCII字碼轉換成字元。
ex.Chr(72)
結果:H

CInt(運算式)
轉換成整數變數型態。
ex.CInt("3.12")
結果:3

CLng(運算式)
轉換成LONG變數型態。

CSng(運算式)
轉換成SINGLE變數型態。

CStr(運算式)
轉換成字串變數型態。

Date()
傳回系統的日期。
ex.Date ()
結果:2000/5/13

DateAdd(I , N , D)
將一個日期加上一段期間後的日期。I:設定一個日期(Date)所加上的一段期間的單位。譬如interval="d"表示N的單位為日。
I:的設定值如下:
yyyy Year 年
q Quarter 季
m Month 月
d Day 日
w Weekday 星期
h Hour 時
n Minute 分
s Second 秒
N:數值運算式,設定一個日期所加上的一段期間,可為正值或負值,正值表示加(結果為date以後的日期),負值表示減(結果為date以前的日期)。
D:待加減的日期。
ex.DateAdd("m" , 1 , "31-Jan-98")
結果:28-Feb-98
說明:將日期31-Jan-98加上一個月,結果為28-Feb-98而非31-Fe-98。
例子:DateAdd("d" , 20 , "30-Jan-99")
結果:1999/2/9
說明:將一個日期30-Jan-99加上20天後的日期。

DateDiff(I , D1 , D2[,FW[,FY]])
計算兩個日期之間的期間。
I:設定兩個日期之間的期間計算之單位。譬如I="m"表示計算的單位為月。I 的設定值如:
yyyy Year 年
q Quarter 季
m Month 月
d Day 日
w Weekday 星期
h Hour 時
m Minute 分
s Second 秒
D1 ,D2:計算期間的兩個日期運算式,若date1較早,則兩個日期之間的期間結果為正值;若date2較早,則結果為負值。
FW:設定每週第一天為星期幾,若未設定表示為星期天。FW的設定值如下:
0 使用API的設定值。
1 星期天
2 星期一
3 星期二
4 星期三
5 星期四
6 星期五
7 星期六
FY:設定一年的第一週,若未設定則表示一月一日那一週為一年的第一週。FY的設定值如下:
0 使用API的設定值。
1 一月一日那一週為一年的第一週
2 至少包括四天的第一週為一年的第一週
3 包括七天的第一週為一年的第一週
ex.DateDiff("d","25-Mar-99","30-Jun-99")
結果:97
說明:顯示兩個日期之間的期間為97天。

DatePart(I,D,[,FW[,FY]])
傳回一個日期的之部份。
I:設定傳回那一部份。譬如I="d"表示傳回部份為日。I的設定值如下:
yyyy Year 年
q Quarter 季
m Month 月
d Day 日
w Weekday 星期
h Hour 時
m Minute 分
s Second 秒
D:待計算的日期。
FW:設定每週第一天為星期幾,若未設定則表示為星期天。FW的設定值如下:
0 使用API的設定值。
1 星期天
2 星期一
3 星期二
4 星期三
5 星期四
6 星期五
7 星期六
FY:設定一年的第一週,若未設定則表示一月一日那一週為一年的第一週。FY的設定值如下:
0 使用API的設定值。
1 一月一日那一週為一年的第一週
2 至少包括四天的第一週為一年的第一週
3 包括七天的第一週為一年的第一週
ex.DatePart("m","25-Mar-99")
結果:3
說明:顯示傳回一個日期的月部份。

Dateserial(year,month,day)
轉換(year,month,day)成日期變數型態。
ex.DateSerial(99,10,1)
結果:1999/10/1

DateValue(日期的字串或運算式)
轉換成日期變數型態,日期從January 1,100 到December 31,9999。格式為month,day,and year或month/day/year。譬如:December 30,1999、Dec 30,1999、12/30/1999、12/30/99
ex.DateValue("January 1,2002")
結果:2002/1/1

Day(日期的字串或運算式)
傳回日期的「日」部份。
ex.Day("12/1/1999")
結果:1

Fix(運算式)
轉換字串成整數數字型態。與Int函數相同。若為null時傳回null。
Int(number)與Fix(number)的差別在負數。如Int(-5.6)=-6,Fix(-5.6)=-5。
ex.Fix(5.6)
結果:5

Hex(運算式)
傳回數值的十六進位值。若運算式為null時Hex(運算式)=null,若運算式=Empty時Hex(運算式)=0。16進位可以加「&H」表示,譬如16進位&H10表示十進位的16。
ex.Hex(30)
結果:1E

Hour(時間的字串或運算式)
傳回時間的「小時」部份。
ex.Hour("12:30:54")
結果:12

InStr([start,]string1,string2[,compare])
將一個字串由左而右與另一個比較,傳回第一個相同的位置。
start為從第幾個字比較起,若省略start則從第一個字比較起,string1為待尋找的字串運算式,string2為待比較的字串運算式,compare為比較的方法,compare=0表二進位比較法,compare=1表文字比較法,若省略compare則為預設的二進位比較法。
ex.InStr("abc123def123","12")
結果:4

InstrRev([start,]string1,string2[,compare])
將一 個字串由右而左與另一個比較,傳回第一個相同的位置。
start為從第幾個字比較起,若省略start則從第一個字比較起,string1為待尋找的字串運算式,string2為待比較的字串運算式,compare為比較的方法,compare=0表二進位比較法,compare=1表文字比較法,若省略compare則為預設的二進位比較法。
ex.InstrRev("abc123def123","12")
結果:10

Int(運算式)
傳回一個數值的整數部份。與Fix函數相同。
Int(5.6)
結果:5

IsArray(變數)
測試變數是(True)否(False)是一個陣列。
ex.IsArray(3)
結果:False
說明:不是一個陣列。

IsDate(日期或字串的運算式)
是否可以轉換成日期。日期從January 1,100 A.D.到December 31,9999 A.D。
ex.IsDate("December 31,1999")

IsEmpty(變數)
測試變數是(True)否(False)已經被初始化
ex.IsEmpty(a)
結果:True

IsNull(變數)
測試變數是(True)否(False)不是有效的資料。
ex.IsNull("")
結果:False
說明:是有效的資料。

IsNumeric(運算式)
是(True)否(False)是數字。
ex.IsNumeric("abc123")
結果:False

LCase(字串運算式)
轉換字串成小寫。將大寫字母的部份轉換成小寫。字串其餘的部份不變。
ex.LCase("ABC123")
結果:abc123

Left(字串運算式,length)
取字串左邊的幾個字。length為取個字。Len函數可得知字串的長度。
ex.Left("ABC123",3)
結果:ABC

Len(字串運算式〡變數)
取得字串的長度。
ex.Len("ABC123")
結果:6

LTrim(字串運算式)
除去字串左邊的空白字。RTrim除去字串右邊的空白字,Trim函數除去字串左右兩邊的空白字。
ex.LTrim("456+" abc ")
結果:456abc123

Mid(字串運算式,start[,length])
取字串中的幾個字。start為從第幾個字取起,length為取幾個字,若略length則從start取到最右底。由Len函數可得知字串的長度。
ex.Mid("abc123",2,3)
結果:c12

Minute(日期的字串或運算式)
傳回時間的「分鐘」部份。
ex.Minute("12:30:54")
結果:30

Month(日期的字串或運算式)
傳回日期的「月」部份。
ex.Month("12/1/2001")
結果:12

MonthName(month[,abbreviate])
傳回月的名稱。
month:待傳回月名稱的數字1~12。譬如,1 代表一月,7代表七月。
abbreviate:是(True)否(False)為縮寫,譬如March,縮寫為Mar。預設值為False。中文的月名稱無縮寫。
ex.MonthName(7)
結果:七月

Now()
傳回系統的日期時間。
ex.Now()
結果:2001/12/30 10:35:59 AM

Oct()
傳回數值的八進位值。八進位可以加「&O」表示,譬如八進位&O10表示十進位的8。
ex.Oct(10)
結果:12

Replace(字串運算式,findnreplacewith[,start[,count[,compare]]])
將一個字串取代部份字。尋找待取代的原字串(find),若找到則被取代為新字串(replacewith)。
find:待尋找取代的原字串。
replacewith:取代後的字。
start:從第幾個字開始尋找取代,若未設定則由第一個字開始尋找。
count:取代的次數。若未設定則所有尋找到的字串取代字串全部被取代。
compare:尋找比較的方法,compare=0表示二進位比較法,compare=1表文字比較法,compare =2表根據比較的資料型態而定,若省略compare則為預設的二進位比較法。
ex.Replace("ABCD123ABC","AB","ab")
結果:abCD123abC

Right(字串運算式,length)
取字串右邊的幾個字,length為取幾個字。Len函數可得知字串的長度。
ex.Right("ABC123",3)
結果:123

Rnd[(number)]
0~1的隨機亂數值。number是任何有效的數值運算式。若number小於0表示每次得到相同的隨機亂數值。number大於0或未提供時表示依序得到下一個隨機亂數值。 number=0表示得到最近產生的隨機亂數值。為了避免得到相同的隨機亂數順序,可以於Rnd函數前加Randomize。
ex.Rnd
結果:0.498498

Round(數值運算式[,D])
四捨五入。
D:為四捨五入到第幾位小數,若省略則四捨五入到整數。
ex.Round(30635,1)
結果:3.6

RTrim(字串運算式)
除去字串右邊的空白字。LTrim除去字串左邊的空白字,Trim函數除去字串左右兩邊的空白字。
ex.RTrim(" abc123 ")+"456"
結果:abc123456

Second(時間的字串或運算式)
傳回時間的「秒」部份。
ex.Second(12:30:54")
結果:54

Space(重複次數)
得到重複相同的空白字串。
ex.A"+Space(5)+"B
結果:A B

String(重複次數,待重複的字)
得到重複相同的字串。
ex.例子:String(5,71)
結果:GGGGG

StrReverse(String(10,71))
將一個字串順序顛倒。
ex.StrReverse("ABC")
結果:CBA

Time()
傳回系統的時間。
ex.Time
結果:10:35:59 PM

TimeSerial(hour,minute,second)
轉換指定的(hour,minute,second)成時間變數型態。
ex.TimeSerial(10,31,59)
結果:10:31:59

TimeValue(日期的字串或運算式)
轉換成時間變數型態。日期的字串或運算式從0:00:00(12:00:00 A.M.)到23:59:59(11:59:59 P.M.)。
ex.TimeValue("11:59:59")
結果:11:59:59

Trim(字串運算式)
除去字串左右兩邊的空白字。
ex.Trim(" abc123 ")
結果:abc123

UCase()
轉換字串成大寫。將小寫字母的部份轉換成大寫,字串其餘部份不變。
ex.UCase("abc123")
結果:ABC123

VarType(變數)
傳回一個變數類型。與TypeName函數相同,VarType傳回變數類型的代碼,TypeName傳回變數類型的名稱。
ex.VarType("I love you!")
結果:8

Weekday(日期運算式,[FW])
傳回星期幾的數字。
FW:設定一週的第一天是星期幾。若省略則表1(星期日)。
Firstdayfweek設定值為:1(星期日),2(星期一),3(星期二),4(星期三),5(星期四),6(星期五),7(星期六)。
ex.Weekday("1/1/2000")
結果:7

WeekDayName(W,A,FW)
傳回星期幾的名稱。
W:是(True)否(False)為縮寫。譬如March,縮寫為Mar。預設為False。中文的星期幾名稱無縮寫。
FW:設定一週的第一天是星期幾。若省略表1(星期日)。設定待傳回星期幾的名稱,為一週中的第幾天。
A:1(星期日),2(星期一),3(星期二),4(星期三),5(星期四),6(星期五),7(星期六)。
ex.WeekDayName("1/1/2000")
結果:星期六

Year()
傳回日期的「年」部份。
ex.Year("12/1/2000")
結果:2000

把點陣圖存進ACCESS資料庫

var
Stream1 : TBlobStream;
begin
Stream1 := TBlobStream.Create(Table1Notes, bmRead);
try
Image1.Picture.Graphic.LoadFromStream(Stream1);
finally
Stream1.Free;
end;
end;

UDL檔的用法

利用檔案總管在 C:\ 新增一文字檔案, 將檔名改為 test.udl
然後 ADOConnection1.ConnectionString := ''File Name=C:\test.udl'' 即可
(在 test.udl 檔下點兩下, 就會知道發生什麼事了)

ADOQuery1.SQL.Add('' SELECT * FROM ABC WHERE bnnam=''+#39+Edit1.Text+#39+'' AND bnpwd=''#39+Edit2.Text+#39);

簡單的問題最棘手:稀疏平常的ASP.NET Session Lost問題

1.3.1 問題描述

客戶抱怨,剛剛開發完成的大型ASP.NET站點測試階段一切正常,但是放到生產環境上,運行壓力一大,就會發生Session Lost現象。問題的表現是一個NullReferenceException異常。分析代碼後發現,該NullReferenceException是試圖訪問一個SessionObject時候發生的。該SessionObject應該在前面就已經設置過。問題半年來一共就發生過3次,而且是在3個不同的頁面發生。

1.3.2 制定策略

這個問題困難的地方在於重現的幾率很小,沒有多少詳細觀察的機會。所以,必須制訂非常周全的計畫,以便問題再次發生的時候,獲取足夠多的資訊。如何制訂周密的計畫呢?

思路非常直觀,瞭解Session實現的細節,總結出導致問題的所有可能性,獲取資訊的時候排查所有的可能性。

關於ASP.NET Session的細節,可以參考:

Underpinnings of the Session State Implementation in ASP.NET

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/ASPNetSessionState.asp

有了對Session的理解後,把這個問題分成了下面幾種情況:

1. 客戶使用了負載均衡的環境,但是沒有正確配置基於資料庫或者服務的Session模式。或者是幾台伺服器的Machine key沒有配置成一致。跟客戶確認後排除了這種情況,因為客戶只有一個伺服器,使用的In-Proc。

2. 最簡單的情況就是所有的用戶,所有的session都丟了。這種情況一般發生在In-Proc的session mode上。原因就是appdomain重啟或者IIS進程崩潰。可以通過性能日誌或系統日誌來排查。

3. 稍微麻煩一點的就是某一個用戶的session丟了,而沒有影響到所有用戶。觀察方法是,首先在session start裏面做log, 把每一個session的創建時間以及session id都記錄到本地的一個log裏面,同時往session裏面添加一個測試用的session value。問題發生的時候,在ASP.NET的全局錯誤處理函數中當前的session id讀出來,比較log中的記錄看看這個session是不是剛剛建立的。如果是,很有可能是用戶端的原因導致session id丟了,比如IE crash導致cookie丟失。

4. 如果不是,那就看看測試用的session value是不是丟了。如果這個也丟了,應該是代碼中掉了Session.Clear。

5. 如果測試用的session value沒有丟,情況就變成一個用戶的session裏面的一部分value丟了。很可能是由於用戶的代碼邏輯導致的。解決方法就是通過更詳細的log來定位問題,然後閱讀代碼來檢查。

可以看到,問題的特徵跟潛在的根源是對應的。目的在於區分出這3種情況:

1. 所有用戶的所有Session全沒有了。

2. 一個用戶的Session沒有了。

3. 一個用戶的部分Session沒有了。

針對每種情況,採取的log策略是:

對於第1類情況,可以在Application_Start/End函數中記錄下時間來檢查Appdomain是不是重新啟動過。

對於第2類情況,log檔應該記錄下session id和session創建的時間。以便判斷問題是否是cookie id lost導致的。如果是cookie id lost,那問題就出在用戶端,或者是網路原因。

對於第3類情況,可以在工程中搜索所有Session Clear的調用,每次調用前寫log檔來記錄。如果工程很大,無法逐一添加,可以載入調試器,在Session Clear函數中設定條件中斷點來記錄。

1.3.3 具體操作和結論

總結下來,具體的實現是:

1. 在global.asax檔的session_start中把這個session的創建時間記錄到session裏面。這個創建時間也同時充當測試用的session value。

2. 代碼中對session操作的地方,寫log到以sessionid為檔案名的檔中去。

3. 用log檔記錄每次session的操作,發生在什麼函數,發生的時間,session內容的變化。

4. 當Exception發生的時候,在Exception handler中記錄發生問題的session id和殘留下來的Session value。

這樣,問題發生的時候,根據Exception handler記錄的session id找到log檔,就可以很清楚地得到所需要的資訊。

在做了上述部署之後,等了大約一個星期問題重現了。在log檔中,發現這樣的資訊:

1. 某一個用戶的部分Session丟失。

2. 從Session創建時間看,該Session已經維持很長時間了。

3. 通過檢查Session Clear的調用紀錄,發現丟失的Session的確是由用戶自己的代碼清除的。同時發現這些代碼的運行次序跟設計不吻合。根據設計初衷,在清除Session後,頁面會重定向到一個專門的頁面並重新添加Session,然後繼續操作。但是log表明這個專門的頁面並沒有得到執行。

檢查用戶的重定向代碼後發現,重定向是通過用戶端JavaScript來實現的。用JavaScript來維護事務邏輯,犯了web開發的大忌。因為JavaScript的行為對用戶端流覽器的依賴非常大。重定向最好用http 302來實現(Response.redirect就是這樣實現的),同時需要在伺服器端添加檢測代碼來確保業務邏輯的正確順序:

HTTP Status code definition

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

在做了上面的改動後,問題得到了解決。Session lost不是一個很有趣的例子,但它卻非常具有代表性。

問題現象簡單而且明確,但是很難重現。問題的原因是在早期積累下來的,如果只觀察問題暴露出來後的現象,為時已晚。對付這類問題,關鍵在於根據問題的特點,在適當的地方主動抓取資訊。

1.3.4 題外話和相關討論

排查session lost的經驗

除了上面的步驟外,遇上session lost還應該注意。

1. 如果用戶開兩個IE進程(注意,不是用Ctrl+N開兩個IE視窗) 訪問同一個url, 這兩個進程分別對應兩個獨立的session。

2. 最容易忽視的情況是session timeout。可以觀察Session id是否變化,或者在session end裏面加log進行排查。

善用規則運算式(Regular Expressions)

如果你非要用字串串連的方式建立 SQL 查詢的話,你就要自己篩選輸入資料。以下範例使用規則運算式過濾特殊字元及部份關鍵字:

string inputString = txtSearch.Text;inputString = Regex.Replace(inputString, @"\b(exec(ute)?|select|update|insert|delete|drop|create)\b|[;']|(-{2})|(/\*.*\*/)", string.Empty, RegexOptions.IgnoreCase);

請注意,如果是使用 LIKE 來執行字串比較,即便是使用參數型命令,你仍需要逸出萬用字元:

Regex re = new Regex(@"(?[\[\%_])");inputString = re.Replace(inputString, "[${EscapeChar}]");

CrystalReport報表匯出成PDF格式的語法

doc.ExportToHttpResponse(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, Response, State, Server.UrlEncode("ATM繳費單"))

設定時間同步的語法

:: 設定要同步的 NTP Server
w32tm /config /update /manualpeerlist:ntp.ntu.edu.tw
:: 開始進行同步
w32tm /resync

FRAMESET中,會遺失工作階段變數(ex.session)的解決方法

如果您使用 Internet Explorer 6 中的 FRAMESET,會遺失工作階段變數
您可以在 P3P 壓縮原則標頭加入您的子內容,而您可以宣告沒有惡意的動作會執行與使用者的資料。 如果 Internet Explorer 偵測到令人滿意的原則,Internet Explorer 會允許設定 Cookie。

請造訪下列 MSDN 網站令人滿意,並不令人滿意的原則程式碼的完整清單:

在 Internet Explorer 6 中的隱私權
http://msdn.microsoft.com/workshop/security/privacy/overview/privacyie6.asp

簡單的壓縮原則符合此條件,如下:
P3P: CP="CAO PSA OUR"

這個程式碼範例會示範您的網站提供您自己的連絡人資訊 (CAO),任何分析的資料是唯一"pseudo-analyzed 」,表示資料給您的線上人物代表,而非您實體的身分 (PSA),連接的並且您的資料未提供任何外部機構,這些機構使用 (OUR) 的存取。

您可以設定此標頭,如果您在 ASP 網頁中使用 Response.AddHeader 方法。 在 ASP.NET 中,您可以使用 Response.AppendHeader 方法。 您可以使用 [IIS 管理嵌入式管理單元 (inetmgr),若要新增至靜態的檔案。

請遵循這些步驟來此標頭加入靜態檔案:
1. 按一下 [ 開始 ]、 按一下 [ 執行 ],然後再輸入 inetmgr ]。
2. 在 [左邊的瀏覽] 頁面按一下 [適當的檔案或目錄,在您想要新增標頭,以滑鼠右鍵按一下的檔案,然後按一下 [ 內容 您網站上]。
3. 按一下 [ HTTP 表頭 ] 索引標籤。
4. 在 [ 自訂 HTTP 表頭 ] 群組方塊中,按一下 [ 新增 ]。
5. 輸入標頭名稱, P3P ,然後壓縮原則的字串輸入 CP =...,其中"...是您的壓縮原則的適當程式碼。
或者,Internet Explorer 使用者可以修改其隱私權設定,這樣會提示他們接受協力廠商的內容。 下列步驟顯示如何修改隱私權設定:
1. 執行的 Internet Explorer。
2. 按一下 [ 工具 ],然後按一下 [ 網際網路選項 。
3. 按一下 [ 隱私 ] 索引標籤,然後按一下 [ 進階 ]。
4. 按一下以選取 [ 覆寫自動 Cookie 處理 ] 核取方塊。
5. 若要以便 ASP 和 ASP.NET 工作階段 Cookie 設定按一下以選取 [ 永遠允許工作階段 Cookie ] 核取方塊。
6. 若要接收任何類型的第三方 Cookie 提示,] 按一下 [ 提示 第三方 Cookie ] 清單中。

MSSQL 權限設定回復方法

declare @dbname nvarchar(200), @cmd2 nvarchar(2000)
declare c_db cursor for
select name from sysdatabases where dbid > 4
open c_db fetch next from c_db into @dbname
while @@fetch_status=0
begin
print @dbname
set @cmd2='use '+@dbname + ' ' +
'
declare @name nvarchar(200), @cmd nvarchar(200)
declare c_user cursor for
select name from sysusers where altuid is null and createdate > ''2001/1/1''


open c_user
fetch next from c_user into @name
while @@fetch_status=0
begin
print @name
exec sp_change_users_login ''Auto_Fix'', @name
fetch next from c_user into @name
end
close c_user
deallocate c_user
'
exec (@cmd2)
--print (@cmd2)
fetch next from c_db into @dbname
end
close c_db
deallocate c_db

--altuid is null (SQL Server 2008) §令 altuid = 0 (SQL Server 2000)
-- exec sp_change_users_login ''Update_One'',@name,@name (SQL Server 2008)
-- ''Auto_Fix'', @name (SQL Server 2000)

匯出PDF檔時,檔名為中文的解決方法

Response.AddHeader("Content-disposition", "attachment; filename=" & Server.UrlEncode("二技報名表") & ".pdf")

修改MSSQL 的連線逾時設定

SQL Server 本機用 Enterprise Manager 用 工具->選項->進階,加大逾時秒數。
或是用指令
USE master
GO
EXEC sp_configure 'remote query timeout', 1200
GO
RECONFIGURE
GO
1200 代表的是秒(SQL Server預設是 600 秒,),設為0表示永不逾時。

若需幕後處理,前端可產生「載入中」圖示的作法

使用 mask.js ,語法如下:
DocumentMask('載入中...');
DocumentUnMask();

如需延長mask的時間
setTimeout("DocumentUnMask();", 1500);

IE8 相容模式 (相容IE7)

來源:諾雅的隨手札記-noah's blog  By noah on 2009/03/19

IE8於2009/3/20正式 Release ,原則上 IE 8 可正常瀏覽器於所有的網頁,如果不幸負責的頁面或自己的站台發生了破版、CSS跑掉及其他可怕的問題時,可以作某些設定,將瀏覽器強迫用相容模式執行,相容模式的意思是改用IE7的方式執行。至於為何會有這種問題,這裡就不細細說明.........


方法一, 如果不是所有頁面都有問題,可以在有問題的那一頁加入Meta 宣告,語法:



此語法是加在 之間。但如果是整個站台有問題,那建議調整 Web Server的設定。可改用下方法。

方法二,如果Web Server為 Apache 環境:

1.確認 apache 有載入 mod_headers 模組(細節請看:Apache官網 )

2.在 httpd.conf 裡加入

Header set X-UA-Compatible "IE=EmulateIE7"

3.重啟 Apache

方法三,如果Web Server為 IIS 環境:

1.進入到 IIS 管理中心,打開 HTTP標題 頁籤,按下「新增」

















2.在自訂標頭名稱輸入「X-UA-Compatible」、自訂標頭值輸入「IE=EmulateIE7」





3.按下套用,或直接按確定


GridView分頁後又可匯出完整內容

protected void Button1_Click(object sender, EventArgs e)
{
GridView1.AllowPaging = false;
GridView1.DataBind();
GridView1.DataSource = (DataTable)ViewState["ExportTable"];
string excelFileName = "Result.xls";
Response.Clear();
Context.Response.AddHeader("content-disposition", "attachment;filename=" +
Server.UrlEncode(excelFileName));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Context.Response.ContentType = "application/vnd.xls";
Response.Charset = "utf-8"; // "big5";
System.IO.StringWriter tw = new System.IO.StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(tw);
this.GridView1.RenderControl(hw);
Context.Response.Write(tw.ToString().Replace("", "").Replace("", ""));
Context.Response.End();
GridView1.AllowPaging = true;
GridView1.DataBind();
}

ESCAPE

 Escape()


不編碼的符號包括: @*/+

escape 不編碼 + (加號), 將使表單欄位資料中有空白的處理(用 + 連結字串)造成問題。
且 escape 在處理非 ASCII 語系的字元會有問題。所以, 除非特例, 應盡量避免使用 escape()。

Cookies的Expires屬性設定

response.cookies("cookiename").expires中expires的屬性如下:


response.cookies("cookiename").expires=-1 表示網頁顯示之後過期
response.cookies("cookiename").expires=0 立即過期
response.cookies("cookiename").expires=data +10 當前時間+10天數 表示在10天以後過期了.
response.cookies("cookiename").expires=10 表示10分鐘後過期..

單獨表示是以分鐘來做單位的,session的單位也是的,但是和date + 10 就不一樣了 ,因為date是日期,日期的單位是天,10當然就變成天了。

以上就是設置過期時間的,但是單位是“天”,就是說這個cookie過一天才會無效,如果想讓它在半小時或更短的時間就無效要怎麼做呢?

response.cookie("cookiename").expires=dateadd("n",30,now())

"n"單位為“分鐘” 或者

response.cookie("cookiename").expires=dateadd("s",1800,now()) "s"單位為“秒”

Response.Cookies["userID"].Expires = System.DateTime.Now.AddMinutes(10);

ASP No Cache

on error resume next
response.expires = 0
response.expiresabsolute = Now() - 1
response.addHeader "pragma","no-cache"
response.addHeader "cache-control","private"
Response.CacheControl = "no-cache"

解決在Google Chrome下不能安裝Adobe Flash Player的問題

1. 首先下載 Flash Player xpi for Windows 。
2. 將下載回來的"flashplayer-win.xpi" 檔案後面加上".zip" 變成 "flashplayer-win.xpi.zip"。
3. 將上列的檔案解壓後,會看到幾個檔案,將其中的 "flashplayer.xpt" 及 "NPSWF32.dll" 複製到
    "C:Documents and SettingsuserLocal SettingsApplication DataGoogleChromeApplicationPlugins" (XP)
    或 "C:UsersuserAppDataLocalGoogleChromeApplicationPlugins" (Vista),而上面的 "user" 請改為你
    的 Windows login 名稱。如果你找不到上列的路徑,可能是你之前選擇了隱藏系統資料夾的
    關係,只要開啟”我的電腦”,選擇”工具>>資料夾選項>>檢視”,點選”顯示所有
    檔案和資料夾”便會再看到。另外,如果在chromeApplication內沒有Plugins的資料夾,自行開
    一個"Plugins" 的資料夾便可以了。
4. 從新開啟Google Chrome,便可以看到Flash 的網頁及Youtube了。

在VS 2008 開發 Silverlight 2,建議安裝順序

假如在VS 2008 開發 Silverlight 2,建議安裝的順序為:VS 2008、VS 2008 SP1、Silverlight 2 Tools、Expression Studio 2、Blend 2 SP1

在VS 2005使用MSCHART注意事項

1. 在網站加入 LinqBridge.dll、System.Web.DataVisualization.Design.dll、

System.Web.DataVisualization.dll 三個參考。
2. 工具箱 --> 選擇項目 --> 加入 System.Web.DataVisualization.dll 後會
    出現控制項(資料頁籤)
3.再將Web.config 複製到網站下(不然會出現控制項錯誤的情形)

使用Chart Director提供的Sample檔

1. 將C:\program Files\chartdirector\VBNetASP 目錄 copy
    到應用程式的目錄下(ex. D:\VS2005\char1)
2. 再開啟Sample檔即可瀏覽內容及SourceCode

在VS 2005安裝Chart Director元件的方式

    1. 在 [工具箱] 空白處 --> 按右鍵
    2. 加入索引標籤 -->  輸入 [ ChartDirector] 
    3. 在 該標籤下方空白處按右鍵 --> 選擇項目 -->
        選擇 .NerFramwork元件 --> 瀏覽 -->
        選擇C:\program Files\chartdirector\bin\netchartdir.dll 檔
        --> 確定

2009年11月25日 星期三

在VS 2005 網站中使用 Chart Director的方式

1. 安裝程式
2. 開啟VS2005
3. 開新網站
4. 在 [方案總管] 中的網站名稱上 --> 按右鍵  --> 加入參考 --> 瀏覽 
    --> 選擇 C:\program Files\chartdirector\bin\netchartdir.dll 檔 --> 確定
5. 將C:\program Files\chartdirector\bin 目錄 copy到 應用程式的目錄下(ex. D:\VS2005\char1)