简体   繁体   中英

How to handle this routing?

I have URL's like:

  • /nl/blog (shows overview of blog items)
  • /nl/blog/loont-lekker-koken-en-wordt-eerlijkheid-beloond (shows blog item with urltitle)
  • /nl/blog/waarom-liever-diëtist-dan-kok (shows blog item with urltitle)

for which I have defined routes:

  • A: route "nl/blog/{articlepage}" with constraint articlepage = @"\\d"
  • B: route "nl/blog"
  • C: route "nl/blog/{urltitle}/{commentpage}" with constraint commentpage = @"\\d"
  • D: route "nl/blog/{urltitle}"

Question 1: this works fine, but maybe there's a better solution with less routes?

Question 2: to add a new article, I have an action method AddArticle in BlogController. Of course, with the routes defined above, the url "/nl/blog/addarticle" would map to route D, where addarticle would be the urltitle which is not correct of course. Therefore I added the following route:

  • E: route "nl/blog/_{action}"

and so now the url "/nl/blog/_addarticle" maps to this route, and execute the correct action method. But I was wondering whether there is a better way to handle this?

Thanks for the advice.

Answers to my own questions:

For question one, I created a custom constraint IsOptionalOrMatchesRegEx:

public class IsOptionalOrMatchesRegEx : IRouteConstraint
{
    private readonly string _regEx;

    public IsOptionalOrMatchesRegEx(string regEx)
    {
        _regEx = regEx;
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        var valueToCompare = values[parameterName].ToString();
        if (string.IsNullOrEmpty(valueToCompare)) return true;
        return Regex.IsMatch(valueToCompare, _regEx);
    }
}

Then, routes A and B can be expressed in one route:

  • url: "nl/blog/{articlepage}"
  • defaultvalues: new { articlepage = UrlParameter.Optional }
  • constraints: new { articlepage = new IsOptionalOrMatchesRegEx(@"\\d")

For question 2, I created an ExcludeConstraint:

public class ExcludeConstraint : IRouteConstraint
{
    private readonly List<string> _excludedList;

    public ExcludeConstraint(List<string> excludedList)
    {
        _excludedList = excludedList;
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        var valueToCompare = (string)values[parameterName];
        return !_excludedList.Contains(valueToCompare);            
    }
}

Route D could then be changed like:

  • url: "nl/blog/{urltitle}"
  • constraints: new { urltitle = new ExcludeConstraint(new List() { "addarticle", "addcomment", "gettags"}) }));

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