Of course you could have additional routes defined and at some later point you may modify the route patterns. You need to have a robust way to generate a URL given a particular collection of route parameters. ie you need to be able to ask the question “Given the country is UK, the language is EN-GB, the article id is 777 and the title is Blah blah blah, what URL do I need to make this hyperlink work?”. The routing infrastructure can do this for you. You need theGetVirtualPath method on a RouteCollection.
GetVirtualPath(RequestContext, RouteValueDictionary)
The static property RouteTable.Routes is of type RouteCollection so we can call RouteTable.Routes.GetVirtualPath()to get the VirtualPathData (which has a VirtualPath property that will give us the URL). All we need to do is create aRouteValueDictionary of our route data and pass the System.Web.Routing.RequestContext. This gets a little trickier as we don’t, by default, have access to the RequestContext at the point when we’re rendering a response. What we can do is push the RequestContext into the HttpContext in our IRouteHandler. Something like this:
Public Class RouteHandler
Implements IRouteHandler
Function GetHttpHandler(ByVal requestContext As System.Web.Routing.RequestContext) _
As IHttpHandler Implements IRouteHandler.GetHttpHandler
requestContext.HttpContext.Items("RequestContext") = requestContext
Return New ViewHandler() With { _
.Country = requestContext.RouteData.GetRequiredString("country"), _
.Id = requestContext.RouteData.GetRequiredString("id"), _
.Lang = requestContext.RouteData.GetRequiredString("lang"), _
.Title = requestContext.RouteData.GetRequiredString("title") _
}
End Function
End Class
I’m rendering the response with a simple IHttpHandler and I simply set all the route data as properties on myIHttpHandler so I can render this as part of the response (I only have one “view” so this is the only way to see if things are working):
Public Class ViewHandler
Implements IHttpHandler
#Region "Property Declarations"
' You can imagine what goes in here right?
#End Region
Sub ProcessRequest(ByVal context As HttpContext) _
Implements IHttpHandler.ProcessRequest
Dim rvd = New RouteValueDictionary(New With { _
.country = "UK", _
.lang = "EN-GB", _
.id = "777", _
.title = "Blah blah blah"})
Dim routedurl = _
RouteTable.Routes.GetVirtualPath(context.Items("RequestContext"), rvd).VirtualPath
context.Response.ContentType = "text/html"
Dim htmlString = _
"<html>" + _
"<head>" + _
"<title>Simple View</title>" + _
"</head>" + _
"<body>" + _
"<h1>Simple View</h1>" + _
"<div>" + _
"<ul>" + _
"<li>" + String.Format("Country: {0}", Me.Country) + "</li>" + _
"<li>" + String.Format("Lang: {0}", Me.Lang) + "</li>" + _
"<li>" + String.Format("Id: {0}", Me.Id) + "</li>" + _
"<li>" + String.Format("Title: {0}", Me.Title) + "</li>" + _
"</ul>" + _
"<a href='" + routedurl + "'>A URL generated from a route</a>" + _
"</div>" + _
"</body>" + _
"</html>"
context.Response.Write(htmlString)
End Sub
Public ReadOnly Property IsReusable() As Boolean _
Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
In my IHttpHandler I want to insert a hyperlink in the response. Notice that I create a new RouteValueDictionary with some route data that I want to turn into the URL for the hyperlink. I then call GetVirtualPath() on the RouteCollectionpassing in the RequestContext that I’d previously pushed into the HttpContext. From there, the VirtualPath property gives me the URL string I need to render the hyperlink with the correct href.
Notice in the image of the rendered page to the right (click to see it enlarged):
No comments yet.
RSS feed for comments on this post. TrackBack URL