31 votes

Ajout d'un ID et d'un titre aux bouchons d'URL en ASP.NET MVC

Comment rediriger une requête en ASP.NET MVC vers sa version canonique correcte si une partie de l'URL est manquante ?

En utilisant Stack Overflow comme exemple, le site ajoute le titre de la question à la fin de ses routes, mais utilise l'ID de la question dans la route pour trouver réellement la question. Si le titre est omis, vous serez redirigé vers l'URL correcte.

Par exemple, en visitant l'URL :

stackoverflow.com/questions/9033 

sera redirigé vers

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

Comment cela fonctionne-t-il ?

40voto

Sunday Ironfoot Points 5625

Créez d'abord une route :

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

Ensuite, créez la méthode Action comme suit :

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); 
}

En fait, vous comparez le titre de l'entité dans l'URL avec celui stocké dans la base de données. S'ils ne correspondent pas, vous effectuez une redirection permanente 301. Assurez-vous qu'il s'agit d'une redirection "permanente" (code de statut 301) et non d'une redirection temporaire (302). De cette façon, les moteurs de recherche considéreront qu'il s'agit d'un changement permanent de l'URL et mettront à jour leurs index en conséquence. Cela peut se produire si le titre de votre entité change après qu'un moteur de recherche l'a indexée (par exemple, quelqu'un change le nom du produit).

Une autre chose à savoir, si votre titre autorise du texte libre, vous devez supprimer tous les caractères qui ne sont pas valides pour une URL, et le rendre plus lisible pour les humains et les moteurs de recherche, d'où la méthode UrlEncoder.ToFriendlyUrl dans le code ci-dessus, la mise en œuvre est ci-dessous :

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(); 
    } 
}

Ainsi, lorsque vous écrivez les URL dans la vue, assurez-vous de coder les titres avec cette méthode, par ex.

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

J'ai écrit un article sur ce sujet ici. http://www.dominicpettifer.co.uk/Blog/34/asp-net-mvc-and-clean-seo-friendly-urls

3voto

David Glenn Points 12819

Bien que je ne connaisse pas les spécificités de la gestion de StackOverflow, voici un aperçu de la façon dont vous pourriez le faire.

  • Récupérer la question de la base de données en utilisant l'ID
  • Convertissez le titre de la question stockée en un slug compatible avec l'URL.
  • Si le slug du titre converti ne correspond pas au slug transmis dans l'URL, la redirection se fait en utilisant le slug du titre converti.

Cela permet de s'assurer que l'URL est toujours la bonne et d'éviter d'éventuelles fausses URL embarrassantes

0voto

Palantir Points 11889

Vous devriez vous renseigner sur les mécanismes de routage ASP.net MVC, car Stackoverflow utilise cette technologie. Il s'agit d'une question assez complexe à laquelle il faut répondre ici, mais vous trouverez de nombreuses ressources d'apprentissage, par exemple : http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx

0voto

LiamB Points 7105

Voici un exemple de la façon dont ils puede mais je crois que vous demandez comment le faire et cela devrait fonctionner.

La première étape consiste à mettre en place deux routes dans le fichier Global.asax.

routes.MapRoute("WithQuestion", "questions/{id}/{name}", new { controller = "Questions", action = "Question", id = "1" });
routes.MapRoute("WithoutQuestion", "questions/{id}", new { controller = "Questions", action = "WithoutQuestion", id="1"});

Maintenant, dans notre contrôleur de questions,

    public ActionResult Question(int id)
    {
        //Load the question as we have the name appended.
        // We could actually do a little validation here as well
        return View();
    }

    public ActionResult WithoutQuestion(int id)
    {
        //Load the question object
        //Generate the full URL and redirect
        return Redirect(FullURL)
    }

Il s'agit d'un exemple très basique mais qui montre comment vous pourriez le faire.

0voto

arun Points 38

@sunday j'ai essayé, mais j'ai quand même rencontré un problème. J'ai besoin de donner l'url comme

Produits?id=4&productName=new-blog

Puis j'ai trouvé la solution. Ce site m'a aidé. Nous devons nous assurer que la route personnalisée est au-dessus de la route par défaut.

Maintenant, il fonctionne bien.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X