[筆記][WebAPI][Cookie]在WebAPI中存取Cookie的方式

Cookie 是在以往Web開發過程中,是常用的一個存資訊在Client端的方式。例如:在電商網站中,當使用者第一次進入網站時,可能就會埋一個Cookie在瀏覽器端,藉以觀察這個瀏覽器,他的一些行為模式,而著名的網站觀察GA,也是以如此的模式作為基礎。目前開發轉到WebAPI後,其實WebAPI也可以對於Request的來源進行類似的作法。這篇就來針對在Controller中,對Cookie進行存取的方式,做個整理。最後,會將相關功能抽出,寫在Models中的類別,作為公用的程式,讓之後每個Controller要對Cookie進行存取,可以簡化相關的撰寫。

緣起

Cookie是在以往Web開發過程中,是常用的一個存資訊在Client端的方式。例如:在電商網站中,當使用者第一次進入網站時,可能就會埋一個Cookie在瀏覽器端,藉以觀察這個瀏覽器,他的一些行為模式,而著名的網站觀察GA,也是以如此的模式作為基礎。目前開發轉到WebAPI後,其實WebAPI也可以對於Request的來源進行類似的作法。這篇就來針對在Controller中,對Cookie進行存取的方式,做個整理。最後,會將相關功能抽出,寫在Models中的類別,作為公用的程式,讓之後每個Controller要對Cookie進行存取,可以簡化相關的撰寫。

練習:在Controller中直接針對Cookie存取

首先,在WebAPI的Controller中,直接撰寫存取Cookie的範例程式先。

我們藉由預設的「api/values」這個WebAPI加上讀取與設定Cookie的語法如下:


    ' GET api/values
    Public Function GetValues() As IEnumerable(Of String)

        '取得Cookie
        Dim getUToken As String = getCookie(Request, "UToken")

        '設定Cookie
        Dim Cookie As HttpCookie = New HttpCookie("UToken", "UToken" & Format(Now, "yyyyMMddHHmmss"))
        Cookie.Expires = DateAdd(DateInterval.Minute, 20, Now())

        HttpContext.Current.Response.Cookies.Add(Cookie)

        Return New String() {"value1", "value2", getUToken}
    End Function

    ''' <summary>
    ''' 取得Cookie
    ''' </summary>
    ''' <param name="request">Request</param>
    ''' <param name="CookieName">Cookie的名字</param>
    ''' <returns></returns>
    Public Function getCookie(ByVal request As HttpRequestMessage, ByVal CookieName As String) As String
        Dim Rc As String = ""
        Dim cookie As CookieHeaderValue = request.Headers.GetCookies(CookieName).FirstOrDefault()
        If cookie IsNot Nothing Then
            Rc = cookie(CookieName).Value
        End If
        Return Rc
    End Function

第一次執行時,因為還沒有設定過Cookie,會讀取不到,在第二次之後的執行,會顯示出上一次的Cookie內容。

寫成公用程式 CookieUtil 類別

為了方便之後的其他Controller可以方便的存取Cookie,將相關的內容抽出來,寫成類別。
我們新增一個類別,名為CookieUtil.vb

將Values中的Cookike存取相關的內容,抽出來,放入 CookieUtil 中,相關內容如下:

Imports System.Net.Http
Imports System.Net.Http.Headers

Public Class CookieUtil

    ''' <summary>
    ''' 取得Cookie
    ''' </summary>
    ''' <param name="request">Request</param>
    ''' <param name="CookieName">Cookie的名字</param>
    ''' <returns></returns>
    Public Function getCookie(ByVal request As HttpRequestMessage, ByVal CookieName As String) As String
        Dim Rc As String = ""
        Dim cookie As CookieHeaderValue = request.Headers.GetCookies(CookieName).FirstOrDefault()
        If cookie IsNot Nothing Then
            Rc = cookie(CookieName).Value
        End If
        Return Rc
    End Function

    Public Sub setCookie(ByVal CookieName As String, ByVal CookieValue As String, ByVal CookieExpires As DateTime, ByVal CookieDomain As String, ByVal CookiePath As String)
        '設定Cookie
        Dim Cookie As HttpCookie = New HttpCookie("UToken", "UToken" & Format(Now, "yyyyMMddHHmmss"))
        'Cookie.Expires = DateAdd(DateInterval.Minute, 20, Now())
        With Cookie
            .Expires = CookieExpires
            If CookieDomain <> "" Then
                .Domain = CookieDomain
            End If
            If CookiePath <> "" Then
                .Path = CookiePath
            End If
        End With
        HttpContext.Current.Response.Cookies.Add(Cookie)
    End Sub


End Class

接著改寫Values,改用公用的類別來運作、測試看看是否還如預期。

' GET api/values
Public Function GetValues() As IEnumerable(Of String)
	Dim utilCookie As New CookieUtil

	'取得Cookie
	Dim getUToken As String = utilCookie.getCookie(Request, "UToken")

	'設定Cookie
	'Dim Cookie As HttpCookie = New HttpCookie("UToken", "UToken" & Format(Now, "yyyyMMddHHmmss"))
	'Cookie.Expires = DateAdd(DateInterval.Minute, 20, Now())
	'HttpContext.Current.Response.Cookies.Add(Cookie)
	Dim CookieValue As String = "UToken" & Format(Now, "yyyyMMddHHmmss")
	Dim CookieExpires As DateTime = DateAdd(DateInterval.Minute, 20, Now())

	utilCookie.setCookie("UToken", CookieValue, CookieExpires, "", "")

	Return New String() {"value1", "value2", getUToken}
End Function

如此,Controller 就能使用公用的程式來存取 Cookie 了。

末記

Cookie的存取,在Controller中,經過以上的整理,可以使用自寫的公用程式來處理,這樣方便了許多。Cookie 在 WebAPI 的存取,除了在 Controller 裡面進行外,另外也可以在 「Message Handler」中,這樣的方式,如果您有興趣,可以參考小喵的這一篇「[筆記][WebAPI][MessageHandler]在MessageHandler中讀取(get)寫入(set) Cookie

參考資料:

https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/http-cookies
https://stackoverflow.com/questions/9793591/how-do-i-set-a-response-cookie-on-httpreponsemessage

 

 

 


以下是簽名:


Microsoft MVP
Visual Studio and Development Technologies
(2005~2019/6)