简体   繁体   中英

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:

在此处输入图片说明

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: 在此处输入图片说明

What can I do?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM