十二月 25

要讓ASP與ASP.NET的Session可以共用的話,需要一些技巧

微軟官方作法是使用SQL Server當中介站,相關說明可參考這邊

不過考量到不是每個專案都會用到SQL Server,所以參考較為簡單的方式來解決

請參考Transfer Session Variables from Classic ASP to ASP.NET,範例網站內可下載。或由小站這邊下載

不過需注意的地方是,如果你要傳的資料很敏感,那請記得加密後再傳

且為了避免使用者攔劫資料修改,建議是加上檢查碼,或是加密

ASP.NET收到後再解密

相關網站:

Session 共用與跨網域

Transfer Session Variables from Classic ASP to ASP.NET

How to Share Session State Between Classic ASP and ASP.NET

解決ASP與ASP.NET共存於一專案Session共用問題(StateStitch)





十二月 11

上一篇文章取得Smart Card的APDU Command,說明如何側錄讀卡機的指令與回傳值

這篇文章將實作程式來讀取自然人憑證的卡號

程式參考於使用C#讀取自然人評證卡號

但實作後仍無法正確顯示,所以使用 WinSCard APDU View Utility 來側錄指令後,修改成下面的程式碼

Imports System
Imports System.Text
Imports System.Runtime.InteropServices

Public Class DigitalCard

    Private Structure SCARD_IO_REQUEST
        Public dwProtocol As Integer
        Public cbPciLength As Integer
    End Structure

    '引用 PC/SC(Personal Computer/Smart Card) API WinScard.dll

    <DllImport("WinScard.dll")> _
    Private Shared Function SCardEstablishContext(ByVal dwScope As UInteger, ByVal nNotUsed1 As Integer, ByVal nNotUsed2 As Integer, ByRef phContext As Integer) As Integer
    End Function

    <DllImport("WinScard.dll")> _
    Private Shared Function SCardReleaseContext(ByVal phContext As Integer) As Integer
    End Function

    <DllImport("WinScard.dll")> _
    Private Shared Function SCardConnect(ByVal hContext As Integer, ByVal cReaderName As String, ByVal dwShareMode As UInteger, ByVal dwPrefProtocol As UInteger, ByRef phCard As Integer, ByRef ActiveProtocol As Integer) As Integer
    End Function

    <DllImport("WinScard.dll")> _
    Private Shared Function SCardDisconnect(ByVal hCard As Integer, ByVal Disposition As Integer) As Integer
    End Function

    <DllImport("WinScard.dll")> _
    Private Shared Function SCardListReaders(ByVal hContext As Integer, ByVal cGroups As String, ByRef cReaderLists As String, ByRef nReaderCount As Integer) As Integer
    End Function

    <DllImport("WinScard.dll")> _
    Private Shared Function SCardTransmit(ByVal hCard As Integer, ByRef pioSendPci As SCARD_IO_REQUEST, ByVal pbSendBuffer() As Byte, ByVal cbSendLength As Integer, ByRef pioRecvPci As SCARD_IO_REQUEST, ByRef pbRecvBuffer As Byte, ByRef pcbRecvLength As Integer) As Integer
    End Function

    ''' <summary>
    ''' 取得自然人憑證的卡號
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetCardNumber() As String
        Dim ContextHandle As Integer = 0, CardHandle As Integer = 0, ActiveProtocol As Integer = 0, ReaderCount As Integer = -1
        Dim ReaderList As String = String.Empty '讀卡機名稱列表
        Dim SendPci, RecvPci As SCARD_IO_REQUEST

        Dim SelEFAPDU_1() As Byte = {&H80, &HA4, &H0, &H0, &H2, &H3F, &H0} 'Select Elementary File 的 APDU
        Dim SelEFAPDU_2() As Byte = {&H80, &HA4, &H0, &H0, &H2, &H9, &H0} 'Select Elementary File 的 APDU
        Dim SelEFAPDU_3() As Byte = {&H80, &HA4, &H0, &H0, &H2, &H9, &H3} 'Select Elementary File 的 APDU

        Dim ReadSNAPDU() As Byte = {&H80, &HB0, &H0, &H0, &H10} '由offset 0 讀取 0x10位 Binary 資料的 APDU

        Dim SelEFRecvBytes(1) As Byte '應回 90 00
        Dim SelEFRecvLength As Integer = 2
        Dim SNRecvBytes(17) As Byte '接收卡號的 Byte Array
        Dim SnRecvLength As Integer = 18

        '建立 Smart Card API
        If SCardEstablishContext(0, 0, 0, ContextHandle) = 0 Then

            '列出可用的 Smart Card 讀卡機
            If SCardListReaders(ContextHandle, Nothing, ReaderList, ReaderCount) = 0 Then

                '建立 Smart Card 連線
                If SCardConnect(ContextHandle, ReaderList, 1, 2, CardHandle, ActiveProtocol) = 0 Then

                    RecvPci.dwProtocol = ActiveProtocol
                    SendPci.dwProtocol = RecvPci.dwProtocol

                    RecvPci.cbPciLength = 8
                    SendPci.cbPciLength = RecvPci.cbPciLength

                    '下達 Select FE14 檔的 APDU
                    If SCardTransmit(CardHandle, SendPci, SelEFAPDU_1, SelEFAPDU_1.Length, RecvPci, SelEFRecvBytes(0), SelEFRecvLength) = 0 Then
                        If SCardTransmit(CardHandle, SendPci, SelEFAPDU_2, SelEFAPDU_2.Length, RecvPci, SelEFRecvBytes(0), SelEFRecvLength) = 0 Then
                            If SCardTransmit(CardHandle, SendPci, SelEFAPDU_3, SelEFAPDU_3.Length, RecvPci, SelEFRecvBytes(0), SelEFRecvLength) = 0 Then

                                '下達讀取卡號指令
                                If SCardTransmit(CardHandle, SendPci, ReadSNAPDU, ReadSNAPDU.Length, RecvPci, SNRecvBytes(0), SnRecvLength) = 0 Then
                                    Return Encoding.Default.GetString(SNRecvBytes, 0, 16)
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        End If
        Return ""
    End Function

End Class

使用的話請參考下面程式

    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim DGCard As New DigitalCard
        MsgBox(DGCard.GetCardNumber)
    End Sub




十一月 23

在GridView中如果想要在滑鼠移動時,滑鼠所指到的那一列會變色的話可以用JavaScript來達成

效果就像下面的圖所示,滑鼠所指到的那一列會變成亮黃色,移開後再還原成原本的顏色

20091123_1

20091123_2

以下為程式碼片段,於RowDataBound的事件中綁定JavaScript到Row中

    Private Sub GridView1_RowDataBound(ByVal sender As Object, _
              ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _
              Handles GridView1.RowDataBound
        '滑鼠移入移出效果。
        If e.Row.RowType = DataControlRowType.DataRow Then
            e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=currentcolor;")
            e.Row.Attributes.Add("onmouseover", "currentcolor=this.style.backgroundColor; this.style.backgroundColor='#ffff40';")
        End If
    End Sub




十一月 13

什麼是擴充方法(Extension Method)呢?

簡單的說就是可以讓你自已擴充用的東西(有說跟沒說一樣.....)

不用把擴充方法想的太難,它其實也是很平易近人的

在寫程式的時候,在字串的後面點(.)下去,會跑出一堆方法讓你使用,最常見的就是ToString()

那麼我們要如何自行設計一個屬於自己的方法呢(結果如下圖)?其實不難

20091113_1

下程的範例程式(專案打包點我下載),研究一下應該就可以懂了

首先撰寫要自訂擴充的方法 ModuleExt.vb

這邊需要注意的地方,在於傳入的參數型態

如果傳入的參數型態是Integer,那麼只有型態是Integer的點下去才會出這個自訂的Method

如果想要任何型態點下去,都會帶出現我們自定的Method,

那麼就把型態定為Object就可以了(如本例的AddString)

Imports System.Runtime.CompilerServices

Namespace ExtensionMethods
    Module OtherExtensions

        ''' <summary>
        ''' 英文字首轉大寫
        ''' </summary>
        <Extension()> _
        Public Function ToUpperFirstWord(ByVal src As String) As String
            If src.Length >= 1 Then
                Dim FirstWord As String = src.Substring(0, 1).ToUpper
                src = src.Remove(0, 1).Insert(0, FirstWord)
            End If
            Return src
        End Function

        <Extension()> _
        Public Function ToPerCent(ByVal src As Double) As String
            Return src * 100 & "%"
        End Function

        <Extension()> _
        Public Function AddString(ByVal src As Object) As String
            Return src & " New AddString"
        End Function

    End Module
End Namespace

接下來則是在要使用的程式頁面引用之前所寫的Extension

Imports ConsoleApplicationTEST.ExtensionMethods.OtherExtensions

Module Module1

    Sub Main()
        Dim test As String = "abcd"
        'Output: Abcd
        Console.WriteLine(test.ToUpperFirstWord)
        'Output: abcd New AddString
        Console.WriteLine(test.AddString)
        'Output: Abcd New AddString
        Console.WriteLine(test.ToUpperFirstWord.AddString)

        'Output: 50%
        Dim testint As Double = 0.5
        Console.WriteLine(testint.ToPerCent)

        Console.ReadLine()
    End Sub

End Module

相關文章:
何謂擴充方法 (Extension method )?
C# 3.0 初體驗:Extension Method
[C#] 3.0 中的新功能 - 擴充方法(Extension Method)





九月 16

PropertyGrid 這個元件在市面上 .net  的書很少看到

這幾天摸了一下,感覺上是個還不錯用的元件

尤其對於在開發"編輯環境"的特別好用

簡單的說,這是一個可以幫你把Class變成設定介面的元件

把Class丟進元件後,元件就會幫你處理傳值與顯示值的問題

看圖或許比較好理解

有沒有一種很熟悉的感覺,沒錯,跟 Visual Studio .Net 的的屬性設定是一樣的

而這個介面只要把寫好的Class放進去就可以自動產生了,真的超方便

完整的程式碼可以到這邊下載

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles MyBase.Load
        '把Class丟進去PropertyGrid
        PropertyGrid1.SelectedObject = New SampleClass
    End Sub

SampleClass.vb

Imports System.ComponentModel

Public Class SampleClass

    <FlagsAttribute()> _
   Public Enum Permissions
        <Description("未設定")> _
        None = 0

        <Description("建立")> _
        Create = 1

        <Description("讀取")> _
        Read = 2

        <Description("更新")> _
        Update = 4

        <Description("刪除")> _
        Delete = 8

        <Description("所有功能")> _
        All = Create Or Read Or Update Or Delete

    End Enum

    Private _P1 As String
    Public Property P1_String() As String
        Get
            Return _P1
        End Get
        Set(ByVal value As String)
            _P1 = value
        End Set
    End Property

    Private _P2 As Integer
    Public Property P2_Integer() As Integer
        Get
            Return _P2
        End Get
        Set(ByVal value As Integer)
            _P2 = value
        End Set
    End Property

    Private _P3 As Boolean
    Public Property P3_Boolen() As Boolean
        Get
            Return _P3
        End Get
        Set(ByVal value As Boolean)
            _P3 = value
        End Set
    End Property

    Private _P4 As DateTime
    Public Property P4_DateTime() As DateTime
        Get
            Return _P4
        End Get
        Set(ByVal value As DateTime)
            _P4 = value
        End Set
    End Property

    Private _P5 As Permissions
    Public Property P5_Enum() As Permissions
        Get
            Return _P5
        End Get
        Set(ByVal value As Permissions)
            _P5 = value
        End Set
    End Property

    Private _P6 As New PropertyTreeClass.AddressType
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    <Description("住址")> _
    Public Property P6_Tree() As PropertyTreeClass.AddressType
        Get
            Return _P6
        End Get
        Set(ByVal value As PropertyTreeClass.AddressType)
            _P6 = value
        End Set
    End Property

    Private _P7 As Color = Color.White
    Public Property P7_Color() As Color
        Get
            Return _P7
        End Get
        Set(ByVal value As Color)
            _P7 = value
        End Set
    End Property

    Private _P8 As Color = System.Drawing.Color.FromArgb(123, 123, 123)
    <Description("於自訂項目的下面空格中按下滑鼠右鍵,可自訂RGB")> _
    Public Property P8_Color() As Color
        Get
            Return _P8
        End Get
        Set(ByVal value As Color)
            _P8 = value
        End Set
    End Property

#Region "可分類的屬性"
    Private _C1 As String
    <Category("分類")> _
    <Description("相同類型的屬性C1")> _
    Public Property C1() As String
        Get
            Return _C1
        End Get
        Set(ByVal value As String)
            _C1 = value
        End Set
    End Property

    Private _C2 As String
    <Category("分類")> _
    <Description("相同類型的屬性C2")> _
    Public Property C2() As String
        Get
            Return _C2
        End Get
        Set(ByVal value As String)
            _C2 = value
        End Set
    End Property
#End Region

End Class

PropertyTreeClass.vb

Imports System.ComponentModel
Imports System.Globalization

'The namespace referenced from
'http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/f81b6caa-5fae-45c4-ad46-2240e84a5d7a

Namespace PropertyTreeClass

    <TypeConverter(GetType(AddressTypeTypeConverter))> _
    Public Class AddressType

        Private m_country As String
        <NotifyParentProperty(True), Description("國家"), RefreshProperties(RefreshProperties.Repaint)> _
        Public Property Country() As String
            Get
                Return m_country
            End Get

            Set(ByVal value As String)
                m_country = value
            End Set
        End Property

        Private m_city As String
        <NotifyParentProperty(True), Description("城市"), RefreshProperties(RefreshProperties.Repaint)> _
        Public Property City() As String
            Get
                Return m_city
            End Get

            Set(ByVal value As String)
                m_city = value
            End Set
        End Property
    End Class

    Public Class Person

        Public Sub New()
            homeAddressField = New AddressType()
        End Sub

        Private homeAddressField As AddressType

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
        Public Property HomeAddress() As AddressType
            Get
                Return Me.homeAddressField
            End Get

            Set(ByVal value As AddressType)
                Me.homeAddressField = value
            End Set
        End Property
    End Class

    Public Class AddressTypeTypeConverter
        Inherits TypeConverter

        Public Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
            'This method is used to shown information in the PropertyGrid.
            If destinationType Is GetType(String) Then
                Return (DirectCast(value, AddressType).Country & ",") + DirectCast(value, AddressType).City
            End If

            Return MyBase.ConvertTo(context, culture, value, destinationType)
        End Function

        Public Overrides Function GetProperties(ByVal context As ITypeDescriptorContext, ByVal value As Object, ByVal attributes As Attribute()) As PropertyDescriptorCollection
            Return TypeDescriptor.GetProperties(GetType(AddressType), attributes).Sort(New String() {"Country", "City"})
        End Function

        Public Overrides Function GetPropertiesSupported(ByVal context As ITypeDescriptorContext) As Boolean
            Return True
        End Function

    End Class

End Namespace