Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

routes - Adding ID and title to URL slugs in ASP.NET MVC

How do you redirect a request in ASP.NET MVC to its correct canonical version if part of the URL is missing?

Using Stack Overflow as an example, the site adds the question title to the end of its routes, but uses the question ID in the route to actually find the question. If the title gets omitted you will be redirected to the correct URL.

For example, visiting the URL:

stackoverflow.com/questions/9033 

will redirect to

stackoverflow.com/questions/9033/hidden-features-of-c

How does this work?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First create a route:

routes.MapRoute( 
    "ViewProduct", 
    "Products/{id}/{productName}", 
    new { controller = "Product", action = "Details", id = "", productName = "" } 
);

Then create the Action method like so:

public ActionResult Details(int? id, string productName) 
{ 
    Product product = ProductRepository.Fetch(id); 

    string realTitle = UrlEncoder.ToFriendlyUrl(product.Title); 
    string urlTitle = (productName ?? "").Trim().ToLower(); 

    if (realTitle != urlTitle)
    { 
        string url = "/Products/" + product.Id + "/" + realTitle; 
        return new PermanentRedirectResult(url);
    } 

    return View(product); 
}

You're basically comparing the entity title in the URL with the one stored in the database, if they don't match then perform a 301 permanent redirect. Make sure it's a 'permanent' redirect (301 status code) instead of a temp redirect (302). This way search engines will treat it as a permanent change of the URL and will update their indexes accordingly, this might happen if the title of your entity changes after a search engine has indexed it (e.g. someone changes the name of the product).

Another thing to be aware of, if your title allows any free text, you need to strip out any characters that are invalid for a URL, and make it more readable for humans and search engines alike, hence the UrlEncoder.ToFriendlyUrl method in the code above, the implementation is below:

public static class UrlEncoder 
{ 
    public static string ToFriendlyUrl (this UrlHelper helper, 
        string urlToEncode) 
    { 
        urlToEncode = (urlToEncode ?? "").Trim().ToLower(); 

        StringBuilder url = new StringBuilder(); 

        foreach (char ch in urlToEncode) 
        { 
            switch (ch) 
            { 
                case ' ': 
                    url.Append('-'); 
                    break; 
                case '&': 
                    url.Append("and"); 
                    break; 
                case ''': 
                    break; 
                default: 
                    if ((ch >= '0' && ch <= '9') || 
                        (ch >= 'a' && ch <= 'z')) 
                    { 
                        url.Append(ch); 
                    } 
                    else 
                    { 
                        url.Append('-'); 
                    } 
                    break; 
            } 
        } 

        return url.ToString(); 
    } 
}

So when you write out the URLs into the View, be sure to encode the titles with this method e.g.

<a href="/Products/@Model.Id/@Url.ToFriendlyUrl(Model.Title)">@Model.Title</a>

I've written a blog post about this here http://www.dominicpettifer.co.uk/Blog/34/asp-net-mvc-and-clean-seo-friendly-urls


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...