Wie kann ich ASP.Net MVC Html.ActionLink Stopp Von der Nutzung der existierenden Routen Werte?

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

  •  08-07-2019
  •  | 
  •  

Frage

Die Website Ich arbeite an hat einige ziemlich komplizierte Routing-Strukturen und wir erleben einige Schwierigkeiten mit der Routing-Engine arbeitet URLs wie wir zu bauen Notwendigkeit sie gebaut werden.

Wir eine Suchergebnisseite, die RegEx basierte Muster können mehrere Variablen in einem einzigen Streckenabschnitt (dh „www.host.com/{structuralParameters}“ verwendet passend zur Gruppe wie folgt sein: „www.host.com/variableA -variableB-variableC“- wo Variablen A bis C sind alle optional). Dies funktioniert gut für uns nach einem bisschen Arbeit.

Das Problem, das wir Entschlüsse um eine störende Eigenschaft der Action Methode erleben: Wenn Sie auf die gleiche Controller / Aktion Punkt wird es die bestehende Route Werte behalten, ob Sie wollen oder nicht. Wir bevorzugen die Kontrolle über das, was unsere Links aussehen und in einigen Fällen kann nicht über die vorhandenen Parameter beibehalten. Ein Beispiel wäre, wo unsere Website Hauptnavigation zu einer Suchergebnisseite führt ohne Parameter festgelegt - eine Standard-Suchseite, wenn Sie möchten. Ich sage dies ist ein ärgerliches Merkmal, weil es ein seltenes Beispiel der ASP.Net MVC-Framework scheinbar diktiert Implementierung ohne offensichtlichen Erweiterungspunkt ist - wir würden es vorziehen, keinen benutzerdefinierte Action Code erstellen Sie einen einfache Navigation Link in unserer Master-Seite zu schreiben

Ich habe einige gesehen sagen, dass Sie solche Parameter explizit festlegen müssen leere Strings sein, aber wenn wir dies versuchen, es ändert sich nur die Parameter von der Route Werte in Query-String-Parameter. Es scheint nicht richtig zu mir, dass wir ausdrücklich Werte sollten verpflichtet werden, auszuschließen wir als Parameter an die Action Methode nicht explizit sind vorbei, aber wenn dies unsere einzige Option ist, werden wir es verwenden. Jedoch derzeit, wenn sie es dann in dem Query-String ist die Anzeige ist als nutzlos für uns als die Parameter direkt in den Weg stellen.

Ich bin mir bewusst, dass unsere Routing-Struktur dieses Problem ärgert - wir würden wahrscheinlich kein Problem haben, wenn wir einen einfacheren Ansatz (dh www.host.com/variableA/variableB/variableC) verwendet, aber unsere URL-Struktur ist nicht verhandelbar -. es wurde entwickelt, um sehr spezifischen Anforderungen gerecht zu werden, um die Benutzerfreundlichkeit, SEO beziehen, und Link / Content-Sharing

Wie können wir Html.ActionLink verwenden Links zu Seiten zu erzeugen, ohne auf den aktuellen Streckendaten zurückzufallen (oder, wenn möglich, um explizit auf Streckenabschnitte ohne), selbst wenn diese Verbindungen zu den gleichen Aktionsmethoden führen?

Wenn wir benoetigen explizit auf Routensegmente ausschließen, wie können wir die Methode von Rendern der Routen als Query-String-Parameter verhindern?

Dieses scheinbar kleine Problem verursacht uns überraschend vielen Kummer und ich werde bei der Lösung es für jede Hilfe dankbar.

EDIT: Wie LukLed angefordert, ist hier eine Probe Action Aufruf:

// 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" } 
);
War es hilfreich?

Lösung

Route Werte einstellen null oder eine leere Zeichenfolge sein, wenn Html.ActionLink oder Html.RouteLink Aufruf (oder eine beliebige URL Generation-Methode) wird die „ambient“ Route Werte löschen.

Zum Beispiel mit dem Standard-MVC-Controller / Aktion / id Route nehme an, Sie sind auf dem "Home / Index / 123". Wenn Sie Html.RouteLink(new { id = 456 }) rufen dann MVC die „ambient“ Route Werte von controller="Home" und action="Index" bemerken. Es wird auch die Umgebungs Route Wert von id="123" bemerken, aber das wird durch die explizite „456“ erhalten überschrieben. Dadurch wird die erzeugte URL dazu führen, dass "Home / Index / 456".

Die Reihenfolge der Parameter zählt auch. Zum Beispiel, sagen Sie Html.RouteLink(new { action = "About" }) genannt. Die „About“ Aktion würde die derzeitige „Index“ Aktion überschrieben werden soll, und die „id“ Parameter würden vollständig erhalten geräumt! Aber warum, fragen Sie? Denn wenn Sie einen Parameter Segment dann alle Parameter Segmente, nachdem sie ungültig werden lassen für ungültig erklärt. In diesem Fall „Aktion“ wurde von einem neuen expliziten Wert für ungültig erklärt, so dass die „id“, die nach ihm kommt, und haben keinen expliziten Wert, wird auch für ungültig erklärt. Somit würde die erzeugte URL sein nur "Home / über" (ohne ID).

In diesem gleichen Szenario, wenn Sie Html.RouteLink(new { action = "" }) riefen dann die erzeugte URL nur „Home“ wäre, weil Sie die „Aktion“ mit einer leeren Zeichenfolge für ungültig erklärt, und dann, dass die „id“ verursacht als auch für ungültig erklärt werden, weil es kam nach die für ungültig erklärt "action".

Andere Tipps

Lösung an der Wurzel des Problems

Es scheint, dass die optimale Lösung (das riecht nicht wie dieses Problem zu umgehen) derjenige ist, der das Problem löst, wo es hat seine Wurzeln, und das ist in Routing.

Ich habe eine benutzerdefinierte Route Klasse namens RouteWithExclusions geschrieben, die der Lage ist, zu routen Wertnamen zu definieren, die ausgeschlossen werden sollen / entfernt werden, wenn URLs zu erzeugen. Das Problem ist, wenn Routing fällt durch Routen-Tabelle und die anschließende Strecken nicht über die gleiche Route Wertnamen ...

Das ganze Problem ist ausführlich und erklärt in mein Blog-Post und der gesamte Code ist ebenfalls vorhanden. Check it out, kann es Ihnen helfen, dieses Routing-Problem zu lösen. Ich habe auch zwei zusätzliche MapRoute Erweiterungsmethoden geschrieben, die einen zusätzlichen Parameter übernehmen.

Wenn Sie die totale Kontrolle über den Link wollen, bauen Sie einfach den Link selbst:

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

Ersatz was Sie brauchen in dem href Attribute.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top