Adam
Adam

Reputation: 6152

Handle dynamic number of optional URL parameters in IIS rewrite rules

My scenario is as follows: a venue can be part of multiple categories and users can also add filters on multiple category types, so my URLs now are like:

  1. /venues/beaches/boats/themeparks (this will display all venues that are beaches AND boats AND themeparks)
  2. /venues/beaches/boats
  3. /venues etc.

So the number of different venue types (beaches, boats, themeparks etc) is both dynamic AND optional. How can I setup my rewrite rules that the category querystring parameter holds all the different venue types or preferably the category parameter is added multipe times and if no venuetype is provided category will just be empty/null?

So for URL: /venues/beaches/boats/themeparks

I'd get this rewritten URL: search.aspx?category=beaches&category=boats&category=themeparks

And for URL: /venues

I'd get this rewritten URL: search.aspx?category= (or fine too would be: search.aspx)

I now just have this:

<rule name="venue types">
  <match url="^venues/([a-zA-Z0-9-+']+)$"/>
  <action type="Rewrite" url="search.aspx?category={R:1}"/>
</rule>

update

I went with the below suggestion of @Arindam Nayak.

I installed https://www.nuget.org/packages/Microsoft.AspNet.FriendlyUrls.Core/ and manually created a RouteConfig.vb file in App_Start folder. I added (as a test):

Public NotInheritable Class RouteConfig
    Private Sub New()
    End Sub
    Public Shared Sub RegisterRoutes(routes As RouteCollection)
        Dim settings = New FriendlyUrlSettings()
        settings.AutoRedirectMode = RedirectMode.Permanent
        routes.EnableFriendlyUrls(settings)

        routes.MapPageRoute("", "test", "~/contact.aspx")

    End Sub
End Class

And in global.aspx.vb I added:

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
    RouteConfig.RegisterRoutes(RouteTable.Routes)
End Sub

When I go to www.example.com/test, it does now correctly redirect me to contact.aspx. (Be aware: URL Rewriting - so rules in web.config or rewriteRules.config file - take precedence over RouteConfig.vb!)

I'm almost there, so this www.example.com/test redirects correctly to file contact.aspx But this www.example.com/test/boats/outside/more/fields/are/here, throws a 404 error:

enter image description here

update 2

I added logging to routeConfig.vb:

    GlobalFunctions.Log("1")
    Dim settings = New FriendlyUrlSettings()
    GlobalFunctions.Log("2")
    settings.AutoRedirectMode = RedirectMode.Permanent
    GlobalFunctions.Log("3")
    routes.EnableFriendlyUrls(settings)
    GlobalFunctions.Log("4")
    routes.MapPageRoute("", "test", "~/contact.aspx")
    GlobalFunctions.Log("5")

And these lines are all executed. Now something strange is happening: routeConfig.vb seems to only be executed once. So:

  1. I build my app.
  2. I goto /test URL
  3. the lines are logged and I arrive on the contact.aspx page
  4. I refresh the /test page, NO lines are logged

And I also tried:

  1. I build my app.
  2. I goto /test/boats/outside/more/fields/are/here URL
  3. the lines are logged
  4. I get the aforementioned 404 error
  5. I refresh the page, nothing is logged anymore

So it seems routeConfig is only ever hit once (at applicationstart?) and then never hit again. And for request /test/boats/outside/more/fields/are/here it arrives at routeConfig.vb file, but does not show contact.aspx for some reason...

update 3

I found that when I explicitly define the routes, it does work, like so:

routes.MapPageRoute("", "test", "~/contact.aspx")
routes.MapPageRoute("", "test/123", "~/contact.aspx")

So now URL /test and /test/123 work, but that is not dynamic at all as I just want to match on /test and then get the FriendlyUrlSegments.

I can't post the code online, so if it helps, here's my solution explorer: enter image description here

What can I do?

Upvotes: 2

Views: 902

Answers (1)

Arindam Nayak
Arindam Nayak

Reputation: 7462

To have such kind of SEO friendly URL you need to install “Microsoft.AspNet.FriendlyUrls” nuget package.

Open package manager console – Help. Then type following –

Install-Package Microsoft.AspNet.FriendlyUrls

Then it will automatically add following in RouteConfig.cs.

public static class RouteConfig
{
   public static void RegisterRoutes(RouteCollection routes)
   {
      var settings = new FriendlyUrlSettings();
      settings.AutoRedirectMode = RedirectMode.Permanent;
      routes.EnableFriendlyUrls(settings); 
    }
}

For you case, you need to add following to RouteConfig.cs.

routes.MapPageRoute("", "venues", "~/venues.aspx");

So when you hit url http://www.example.com/venues/beaches/boats/themeparks or http://www.example.com/venues/beaches, it will hit venues.aspx. In venues.aspx.cs, page_load event you need to have following code.

IList<String> str = Request.GetFriendlyUrlSegments();

For case-1, str will be ['beaches','boats','themeparks'] and for case-2 it will be ['beaches'].

For more info you can refer to my blog or similar SO answer here - Reroute query string using friendlyUrl

Let me know,if you face any issue or still your issue is unresolved.

Upvotes: 1

Related Questions