ASP.NET Routing: How to make routeConfig handle a more dynamic URL structure

☆樱花仙子☆ 提交于 2019-12-18 18:03:55

问题


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. I decided to go with URLRouting so I can start to get the different values in codebehind via Request.GetFriendlyUrlSegments()

I installed https://www.nuget.org/packages/Microsoft.AspNet.FriendlyUrls.Core/ and manually created a RouteConfig.vb file in App_Start folder. This file contains:

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("", "venues", "~/venues.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

I removed ALL rewrite rules from my application, so no rules in web.config or rewriteRules.config. When I go to URL: www.example.com/venues, it correctly redirects me to venues.aspx. But this URL: www.example.com/venues/boats/outside/castles/barns/restaurants, throws a 404 error:

I also checked here and tried that, so enabling http redirection on Windows and changing web.config:

web.config

<!-- tried setting mode to On/Off/Custom -->
<customErrors mode="Off" defaultRedirect="/error/1" redirectMode="ResponseRedirect">
  <error statusCode="404" redirect="/404.aspx" />
</customErrors>

<modules runAllManagedModulesForAllRequests="true">
  <add type="aspnetforum.ForumSEOHttpModule, aspnetforum" name="ForumSEOHttpModule" />
  <remove name="UrlRoutingModule"/>
  <add name="UrlRoutingModule"
       type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />


</modules>
<handlers>
  <remove name="PHP55_via_FastCGI" />
  <remove name="PHP53_via_FastCGI" />
  <add name="ScriptCombiner" verb="POST,GET" path="ScriptCombiner.axd" preCondition="integratedMode" type="ScriptCombiner, App_Code" />

  <add name="UrlRoutingHandler"
              preCondition="integratedMode"
              verb="*"
              path="UrlRouting.axd"
              type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>


</handlers>

I found that when I explicitly define the routes in RouteConfig.vb, it does work, like so:

routes.MapPageRoute("", "venues", "~/venues.aspx")
routes.MapPageRoute("", "venues/boats/outside/castles/barns/restaurants", "~/venues.aspx")

So now URL /venues and /venues/boats/outside/castles/barns/restaurants work, but that is not dynamic at all. Since there are a a lot of venue categories and combinations, I don't want to add all these combinations manually. I just want to match on all URLs that start with /venues and then use method Request.GetFriendlyUrlSegments in venues.aspx.vb to get the venue categories.

How can I do this?


回答1:


I believe you need to add URL patterns to your routes.MapPageRoute call.

A URL pattern can contain literal values and variable placeholders (referred to as URL parameters). The literals and placeholders are located in segments of the URL which are delimited by the slash (/) character.

When a request is made, the URL is parsed into segments and placeholders, and the variable values are provided to the request handler. This process is similar to the way the data in query strings is parsed and passed to the request handler. In both cases variable information is included in the URL and passed to the handler in the form of key-value pairs. For query strings both the keys and the values are in the URL. For routes, the keys are the placeholder names defined in the URL pattern, and only the values are in the URL.

In a URL pattern, you define placeholders by enclosing them in braces ( { and } ). You can define more than one placeholder in a segment, but they must be separated by a literal value. For example, {language}-{country}/{action} is a valid route pattern. However, {language}{country}/{action} is not a valid pattern, because there is no literal value or delimiter between the placeholders. Therefore, routing cannot determine where to separate the value for the language placeholder from the value for the country placeholder.

You can use a couple of different methods to constrain your routes. You can use RegEx, as in:

routes.MapRoute(name := "BlogPost", url := "blog/posts/{postId}", defaults := New With { _
    Key .controller = "Posts", _
    Key .action = "GetPost" _
}, New With { _
    Key .postId = "\d+" _
})

The tiny Regular Expression @"\d+ in the code above basically limits the matches for this route to URLs in which the postId parameter contains one or more digits. In other words, nothing but integers, please.

The other option for using route constraints is to create a class which implements the IRouteConstraint interface.

More info from CodeProject.



来源:https://stackoverflow.com/questions/34080141/asp-net-routing-how-to-make-routeconfig-handle-a-more-dynamic-url-structure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!