步驟1:新增一個Class,然後實作IRouteConstraint 介面,IRouteConstraint 介面只定義一個Match() 方法。
YearMonthDayRouteConstraint.vb
Public Class YearRouteConstraint Implements IRouteConstraint ''' <summary> ''' 實作IRouteConstraint介面Match方法 ''' </summary> ''' <param name="httpContext">包含有關個別 HTTP 要求的 HTTP 專屬資訊。</param> ''' <param name="route">提供用以定義路徑和取得路徑相關資訊的屬性及方法。</param> ''' <param name="parameterName">索引鍵/值組之不區分大小寫的集合</param> ''' <param name="values"></param> ''' <param name="routeDirection">表示 ASP.NET 路由是正在處理來自用戶端的 URL 還是正在產生 URL。</param> ''' <returns>Boolean</returns> ''' <remarks></remarks> Public Function Match(httpContext As System.Web.HttpContextBase, route As System.Web.Routing.Route, parameterName As String, values As System.Web.Routing.RouteValueDictionary, routeDirection As System.Web.Routing.RouteDirection) As Boolean Implements System.Web.Routing.IRouteConstraint.Match ' IncomingRequest, 正在處理來自用戶端的 URL。 ' InvariantCulture, 取得與文化特性無關的 (不變的) System.Globalization.CultureInfo。 If (routeDirection = Routing.RouteDirection.IncomingRequest) AndAlso (parameterName.ToLower(System.Globalization.CultureInfo.InvariantCulture) = "year") Then Try Dim year As Integer = Convert.ToInt32(values("year")) If (year >= 1990) AndAlso (year <= 2100) Then Return True Else Return False End If Catch ex As Exception Return False End Try End If Return False End Function End Class Public Class MonthRouteConstraint Implements IRouteConstraint Public Function Match(httpContext As System.Web.HttpContextBase, route As System.Web.Routing.Route, parameterName As String, values As System.Web.Routing.RouteValueDictionary, routeDirection As System.Web.Routing.RouteDirection) As Boolean Implements System.Web.Routing.IRouteConstraint.Match If (routeDirection = Routing.RouteDirection.IncomingRequest) AndAlso (parameterName.ToLower(System.Globalization.CultureInfo.InvariantCulture) = "month") Then Try Dim month As Integer = Convert.ToInt32(values("month")) If (month >= 1) AndAlso (month <= 12) Then Return True Else Return False End If Catch ex As Exception Return False End Try End If Return False End Function End Class Public Class DayRouteConstraint Implements IRouteConstraint Public Function Match(httpContext As System.Web.HttpContextBase, route As System.Web.Routing.Route, parameterName As String, values As System.Web.Routing.RouteValueDictionary, routeDirection As System.Web.Routing.RouteDirection) As Boolean Implements System.Web.Routing.IRouteConstraint.Match If (routeDirection = Routing.RouteDirection.IncomingRequest) AndAlso (parameterName.ToLower(System.Globalization.CultureInfo.InvariantCulture) = "day") Then Try Dim month As Integer = Convert.ToInt32(values("month")) Dim day As Integer = Convert.ToInt32(values("day")) If (day < 1) Then Return False End If Select Case month Case 1, 3, 5, 7, 8, 10, 12 If (day <= 31) Then Return True End If Case 2 If (day <= 28) Then Return True End If Case 4, 6, 9, 11 If (day <= 30) Then Return True End If End Select Catch ex As Exception Return False End Try End If Return False End Function End Class
YearMonthDayRouteConstraint.vb內含三個Class,都實作了IRouteConstraint 介面,程式很簡單,我們限制年( year )必須在1990 ~ 2100之間,月( month )必須在 1 ~ 12之間,日( day )有分大小月及二月的判斷。
步驟二:接下來我們在 Global.asax 加上一條路由規則,
routes.MapRoute("Archive", "Archive/{year}/{month}/{day}", New With {.contrller = "Archive", .action = "Index", .year = UrlParameter.Optional, .month = UrlParameter.Optional, .day = UrlParameter.Optional}, New With {.year = New YearRouteConstraint, .month = New MonthRouteConstraint, .day = New DayRouteConstraint})
重點在最後一個參數,我們傳入的路由規則的限制條件:
/Archive/2011/5/18 --> OK
/Archive/2011/2/29 --> Bad
此程式還有改進的空間,例如二月的潤月計算,會有29天,2012/2/29應該是要對的。除了寫Class之外,我們也可以直接使用RegEx 來設計限制條件,例如:
routes.MapRoute("Archive2", "Archive/{year}/{month}/{day}", New With {.contrller = "Archive", .action = "Index", .year = UrlParameter.Optional, .month = UrlParameter.Optional, .day = UrlParameter.Optional}, New With {.year = "\d{4}", .month = "\d{2}", .day = "\d{2}"})
如果提供的是字串,路由會將字串視為規則運算式,並且呼叫 Regex 類別的 IsMatch 方法,藉此檢查參數值是否有效。這邊我們規則很簡單,year只要是4位數數字,month及day只要是2位數數字。
以上我們簡單示範如何幫路由設計、撰寫及使用限制條件,這不只是限制,也是安全性的提升。
沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。