Route constraints op QueryString parameters in ASP.NET MVC nl

Door creator1988 op maandag 21 februari 2011 14:11 - Reacties (1)
Categorie: Frontend, Views: 4.962

ASP.NET MVC kent een vrij krachtige routing-engine om URL's te routen naar de actie die daarbij hoort. Naast puur URL's mappen kan je tevens constraints toevoegen om je routings wat te finetunen. Bijvoorbeeld praktisch voor de volgende situatie:

code:
1
2
3
4
5
/koop/amsterdam/appartement-12345-straat-1/fotos/
-> moet naar ObjectController.Detail

/koop/amsterdam/appartement-12345-straat-1/reageer/
-> moet naar ObjectController.Contact


Door een constraint toe te voegen, kan je onderscheid maken tussen deze twee URL's:

C#:
1
2
3
4
5
6
7
8
// bijvoorbeeld
routes.MapRoute(
    "object-contact",
    "{aanbod}/{plaats}/{type}-{id}-{adres}/{pagina}",
    /* ... */,
    new { pagina = @"reageer|bezichtiging" });

// als pagina iets anders is dan reageer / bezichtiging matcht de route niet


Probleem: wanneer je URL's van binnen als volgt zijn (omdat ASP.NET voor elke URL in je website opslaat of er een fysieke file voor is, en bij miljoenen unieke URL's is dat een huge leak dat niet automatisch wordt geflusht):

code:
1
/koop/?id=12345&pagina=reageer


zijn constraints niet meer mogelijk, want dit wordt niet ondersteunt op QueryString parameters. Daarom: de QueryStringConstraint!

In gebruik heel simpel. Voor bovenstaande URL kan je de volgende route schrijven:

C#:
1
2
3
4
routes.MapRoute("object-contact",
    "{aanbod}",
    /* ... */,
    new { pagina = new QueryStringConstraint("bezichtiging|reageer") });


En de werking is exact hetzelfde als normaal. The codez:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class QueryStringConstraint : IRouteConstraint
{
    private readonly Regex _regex;

    public QueryStringConstraint(string regex)
    {
        // ctor slaat de regex op voor further use
        _regex = new Regex(regex, RegexOptions.IgnoreCase);
    }

    public bool Match (HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        // zit de paramName uberhaupt in de QS
        if(httpContext.Request.QueryString.AllKeys.Contains(parameterName))
        {
            // doe dan check op de meegegeven regex
            return _regex.Match(httpContext.Request.QueryString[parameterName]).Success;
        }
        // anders return false
        return false;
    }
}

Volgende: Zoekscherm dat dynamisch queries maakt met Expression Trees en MVC 02-'11 Zoekscherm dat dynamisch queries maakt met Expression Trees en MVC
Volgende: Mobile device detection 02-'11 Mobile device detection

Reacties


Door Tweakers user Jogai, maandag 21 februari 2011 20:49

Handig. Kun je misschien ook eens bloggen over het zoeken in ASP.net MVC? Een goed artikel kon ik er nog niet over vinden. Ik heb het opgelost met een form waarvan de waardes optioneel in een iqueryable worden opgenomen. Dit werkt echter niet heel mooi, en ik verwacht dat er iets eleganters voor is.

Reageren is niet meer mogelijk