Laden...

RouteConfig Zugriff auf den Request

Erstellt von bbb vor 7 Jahren Letzter Beitrag vor 7 Jahren 2.239 Views
B
bbb Themenstarter:in
72 Beiträge seit 2009
vor 7 Jahren
RouteConfig Zugriff auf den Request

Hallo zusammen,

ich suche gerade nach einer Möglichkeit in der RouteConfig auf den Request zuzugreifen. Ich habe folgende Default-Route:


routes.MapRoute(
                name: "Default",
                url: "{culture}/{controller}/{action}/{id}",
                defaults: new { culture = CultureHelper.DetectRequestCulture(HttpContext.Current.Request), controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

Ich möchte gerne auf das Request Object zugreifen, wenn die Default-Route greift. Leider wird an dieser Stelle dann eine Exception geworden:

Fehlermeldung:
"Anforderung steht in diesem Kontext nicht zur Verfügung"

Kennt jemand einen Weg bereits an dieser Stelle den Request entsprechend abzugreifen?

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo bbb,

das Request-Objekt sollte dir im Controller zur Verfügung stehen, wenn ein Request reinkommt. Wie hast dus probiert? In deinem Schnipsel sieht man nur die RouteConfig, die beim Start geladen wird.

Gruss

Coffeebean

16.807 Beiträge seit 2008
vor 7 Jahren

In der Config hast Du keinen Zugriff auf den Context und damit auch nicht auf den Request.

Die Config wird nicht durch Deinen Request ausgeführt und auch nicht jedes mal.
Gehört zum Application Warmup.

Was genau hast Du vor?
Scheint mir irgendwas mit Localization, was man so definitiv nicht in der Form macht.
Simpel würde es gehen mit jeweils definierten Routen.

Komplex aber vollständig geht es mit einer eigenen Route-Klasse.

B
bbb Themenstarter:in
72 Beiträge seit 2009
vor 7 Jahren

Korrekt. Ich versuche darüber eine Lokalisierung zu realisieren. Idee ist die Lokalisierung bereits als Teil der URL zu haben nicht als Parameter. Also zb so:

Website.com/de/Index/Home
Website.com/en/Index/Home

Ich habe dazu einen Base Controller, welcher im BeginExecuteCore Event die culture ausließt:


protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
    string cultureName = RouteData.Values["culture"] as string; 

}

Das klappt auch sehr gut. Mein Ziel ist es nun folgendes Verhalten schon beim Initialen starten der Site zu erlangen:

1.) Hat der User ein Cookie mit einer Spracheinstellung gesetzt, wenn ja nutze dies
2.) Hat er kein Cookie, auslesen der Accept-Language des Browsers
3.) Klappt das nicht setzen der Default Language (zb en)
4.) Möglichkeit bieten den User (zb DrobDown) eine Sprache auszuwählen. Diese Auswahl soll dann im Cookie gespeichert werden.

Meine Idee war nun dieses Verhalten schon beim greifen der Default Route einzubauen, indem ich den culture Teil der URL durch eine Methode setzen lasse, die genau das beschriebene umsetzt.
Falscher Ansatz? Bessere Vorschläge um genau das umzusetzen?

16.807 Beiträge seit 2008
vor 7 Jahren

Da dokterst Du aber an der völlig falschen Stelle rum.
Mach das über einen Filter.

Im Filter liest Du den Cookie und liest die Sprache aus.
Hier, über Google gefunden (erster Treffer): https://gist.github.com/codefrenzy/1583539
Ist zwar als MVC 3 beschrieben geht aber auch weiterhin in 5.

B
bbb Themenstarter:in
72 Beiträge seit 2009
vor 7 Jahren

Ja, das Vorgehen über den Action Filter ist mir auch bekannt. Eignet sich meiner Auffassung nach aber nicht für mein Vorhaben.

Stelle dir folgendes vor: User betritt zum ersten mal die Seite (Cookie nicht vorhanden). Es müsste eine Default route greifen die ihn beispielsweise auf:

Website.com/en/Index/Home

leitet. Seine Browser-Einstellung sagt aber, dass er ein deutscher User ist und eigentlich hier landen müsste:

Website.com/de/Index/Home

Wenn das OnActionExecuting Event des Filters greift wurde der User also schon auf die "en"-Default-Culture geleitet. Was soll denn jetzt geschehen, wenn diese Default-Route für den User unpassend ist? Ein weiterer Redirect zurück mit einer neu ermittelten Culture?

16.807 Beiträge seit 2008
vor 7 Jahren

Das ist ein Thema der Usability und ich muss sagen: ich mag Deine Usability hier nicht.

Du solltest den Benutzer nicht einfach von en auf de umleiten, wenn er explizit en aufruft.
Würde ich so eine Seite haben, würde ich sie wieder verlassen.

Du solltest akzeptieren, dass er explizit en aufgerufen hat.
Nun kannst Du Applikationslogik integrieren:

Wenn kein Cookie gesetzt ist zB

  • Browsersprache ermitteln und nachfragen, ob man umleiten soll
  • so lassen

Wenn ein Cookie gesetzt ist

  • Stimmt die Sprache mit Cookie überein?

Ich zB. nutze meinen Arbeits-PC immer auf Englisch, mein Tablet auf Schwedisch.
Der Browser sendet also entsprechend auch keine deutsche Culture.
Ich will aber zB. Webseiten auch auf Deutsch angezeigt haben und nutze dafür auch oft die Anpassung in der URL.

Ich seh kein Grund, wieso der Filter nicht gehen soll.
Der Filter ist das allgemeine Mittel zur Lokalisierung und mir kam noch kein Fall unter, wo ein Filter nicht funktioniert hätte.

B
bbb Themenstarter:in
72 Beiträge seit 2009
vor 7 Jahren

Ich glaub da hast du mich falsch verstanden. Im Grunde soll wie du beschrieben hast der User vollkommen freie Wahl der Sprache haben. Es geht um den ersten Besuch der Seite. Der User tippt in den Browser www.website.com ein und soll (je nach Browsersprache) zb auf www.website.com/de umgeleitet werden. Dies nur für den ersten Aufruf. Wenn er dann also, wie in deinem Fall auf der schwedischen Version gelandet ist, drückt er einmal auf die deutsche Flagge und hat bei allen zukünftigen Besuchen die deutsche Seite vor sich, da in diesem Fall dann der gesetzte Cookie greift.

Also meine Frage: Wie leite ich den User immer auf den korrekten URL Prefix? Der URL Prefix ist ja meines Erachtens nach schon durch das Routing gesetzt.

16.807 Beiträge seit 2008
vor 7 Jahren

Ich versteh schon was Du willst. Ich hab das auch schon öfter gemacht 😉
Du liest die Cookies einfach im Filter aus und leitest dort um.

B
bbb Themenstarter:in
72 Beiträge seit 2009
vor 7 Jahren

Super, dank dir. Ich werde das nun auf die Weise umsetzen.