Comment puis-je empêcher ASP.Net MVC Html.ActionLink d'utiliser des valeurs de routage existantes?

StackOverflow https://stackoverflow.com/questions/1817421

  •  08-07-2019
  •  | 
  •  

Question

Le site Web sur lequel je travaille a des structures de routage assez complexes et nous éprouvons des difficultés à utiliser le moteur de routage pour créer des URL de la manière dont nous avons besoin de les construire.

>

Nous avons une page de résultats de recherche qui utilise une correspondance de modèle basée sur RegEx pour regrouper plusieurs variables en un seul segment de routage (c'est-à-dire "www.host.com/ {structuralParameters}" peut être le suivant: "www.host. com / variableA-variableB-variableC "- où les variables A à C sont toutes facultatives). Cela fonctionne pour nous bien après un peu de travail.

Le problème que nous rencontrons se résout autour d’une fonctionnalité gênante de la méthode ActionLink: si vous pointez sur le même contrôleur / action, il conservera les valeurs de route existantes, que vous le vouliez ou non. Nous préférons avoir un contrôle sur l'apparence de nos liens et, dans certains cas, nous ne pouvons pas conserver les paramètres existants. Un exemple serait où la navigation principale de notre site mène à une page de résultats de recherche sans paramètres définis - une page de recherche par défaut, si vous voulez. Je dis qu'il s'agit d'une fonctionnalité gênante, car il s'agit d'une instance rare du framework ASP.Net MVC qui semble imposer une implémentation sans un point d'extension évident. Nous préférerions ne pas créer de code ActionLink personnalisé pour écrire un simple lien de navigation dans notre page maître!

J'ai vu certains dire que vous devez définir explicitement ces paramètres comme des chaînes vides, mais lorsque nous essayons cela, cela modifie simplement les paramètres de valeurs de route en paramètres de chaîne de requête. Il ne me semble pas correct de devoir obligatoirement exclure explicitement les valeurs que nous ne transmettons pas explicitement en tant que paramètres à la méthode ActionLink, mais si c'est notre seule option, nous allons l'utiliser. Cependant, à l’heure actuelle, s’il s’affiche dans la chaîne de requête, il nous est aussi inutile que de placer les paramètres directement dans la route.

Je suis conscient que notre structure de routage exaspère ce problème. Nous n'aurions probablement aucun problème si nous utilisions une approche plus simple (c'est-à-dire www.host.com/variableA/variableB/variableC), mais notre structure d'URL n'est pas négociable. - il a été conçu pour répondre à des besoins très spécifiques en matière de convivialité, de référencement et de partage de liens / contenus.

Comment pouvons-nous utiliser Html.ActionLink pour générer des liens vers des pages sans retomber sur les données de route actuelles (ou, si possible, exclure explicitement les segments de route) même si ces liens mènent aux mêmes méthodes d'action?

Si nous devons exclure explicitement les segments de route, comment pouvons-nous empêcher la méthode de rendre les routes en tant que paramètres de chaîne de requête?

Ce problème apparemment mineur nous cause une quantité surprenante de chagrin et je serai reconnaissant de toute aide pour le résoudre.

EDIT: À la demande de LukLed, voici un exemple d'appel ActionLink:

// I've made it generic, but this should call the Search action of the 
// ItemController, the text and title attribute should say "Link Text" but there
// should be no parameters - or maybe just the defaults, depending on the route.
// 
// Assume that this can be called from *any* page but should not be influenced by
// the current route - some routes will be called from other sections with the same
// structure/parameters.
Html.ActionLink( 
    "Link Text",
    "Search", 
    "Item", 
    new { }, 
    new { title = "Link Text" } 
);
Était-ce utile?

La solution

La définition de valeurs de route comme chaînes nulles ou vides lors de l'appel de Html.ActionLink ou Html.RouteLink (ou de toute méthode de génération d'URL) effacera la valeur "ambient". valeurs de route.

Par exemple, avec la route / contrôleur / action / contrôleur MVC standard, supposez que vous êtes sur "Home / Index / 123". Si vous appelez Html.RouteLink (new {id = 456}) , MVC remarquera alors le message "ambient". valeurs de route de controller = "Accueil" et action = "Index" . Il remarquera également la valeur de route ambiante de id = "123" , mais sera écrasé par le "456" explicite. Ainsi, l'URL générée sera "Home / Index / 456".

L'ordre des paramètres est également important. Par exemple, disons que vous avez appelé Html.RouteLink (new {action = " About "}}) . Le " À propos de " une action écraserait le " Index " actuel action, et le "id" paramètre serait effacé entièrement! Mais pourquoi, tu demandes? En effet, une fois que vous avez invalidé un segment de paramètre, tous les segments de paramètres suivants seront invalidés. Dans ce cas, "action". a été invalidé par une nouvelle valeur explicite de sorte que le "id", qui vient après, sans valeur explicite, soit également invalidé. Ainsi, l'URL générée serait simplement " Accueil / À propos de " (sans identifiant).

Dans ce même scénario, si vous appeliez Html.RouteLink (new {action = ""}) , l'URL générée serait alors simplement" Accueil ". parce que vous avez invalidé l'action " action " avec une chaîne vide, et puis cela a provoqué le "id" être invalidée également parce qu'elle est postérieure à "l'action" invalidée.

Autres conseils

Solution à la racine du problème

Il semble que la solution optimale (qui ne sente pas une solution de contournement) soit celle qui résout le problème où il a des racines et qui se trouve dans le routage.

J'ai écrit une classe Route personnalisée appelée RouteWithExclusions , capable de définir des noms de valeur de route devant être exclus / supprimés lors de la génération d'URL. Le problème est que le routage tombe dans la table des routes et que les routes suivantes ne portent pas le même nom de valeur de route ...

L'ensemble du problème est détaillé et expliqué dans mon article de blog et tout le code y est également fourni. Consultez-le, cela peut vous aider à résoudre ce problème de routage. J'ai également écrit deux méthodes d'extension MapRoute supplémentaires qui prennent un paramètre supplémentaire.

Si vous souhaitez contrôler totalement le lien, créez-le vous-même:

<a href="~/variableA/variableB/<%= Html.Encode(Model.Target) %>">Click Here</a>

Substituez tout ce dont vous avez besoin dans l'attribut href .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top