Was ist der beste Ort, um die Kultur / UI-Kultur in einer ASP.net MVC-App festzulegen?
Derzeit habe ich eine CultureController-Klasse, die folgendermaßen aussieht:
public class CultureController : Controller
{
public ActionResult SetSpanishCulture()
{
HttpContext.Session["culture"] = "es-ES";
return RedirectToAction("Index", "Home");
}
public ActionResult SetFrenchCulture()
{
HttpContext.Session["culture"] = "fr-FR";
return RedirectToAction("Index", "Home");
}
}
und einen Hyperlink für jede Sprache auf der Homepage mit einem Link wie diesem:
<li><%= Html.ActionLink("French", "SetFrenchCulture", "Culture")%></li>
<li><%= Html.ActionLink("Spanish", "SetSpanishCulture", "Culture")%></li>
Das funktioniert gut, aber ich denke, es gibt einen angemesseneren Weg, dies zu tun.
Ich lese die Kultur mit dem folgenden ActionFilter: http://www.iansuttle.com/blog/post/ASPNET-MVC-Action-Filter-for-Localized-Sites.aspx . Ich bin ein bisschen ein MVC-Noob, daher bin ich nicht sicher, ob ich dies an der richtigen Stelle einstelle. Ich möchte es nicht auf der Ebene web.config tun, es muss auf der Wahl eines Benutzers basieren. Ich möchte auch nicht ihre http-Header überprüfen, um die Kultur aus ihren Browsereinstellungen zu erhalten.
Bearbeiten:
Nur um klar zu sein - ich versuche nicht zu entscheiden, ob ich eine Sitzung verwenden möchte oder nicht. Ich bin glücklich mit diesem bisschen. Ich versuche herauszufinden, ob es am besten ist, dies in einem Kultur-Controller zu tun, für den für jede Kultur eine Aktionsmethode festgelegt werden soll, oder ob es in der MVC-Pipeline einen besseren Ort gibt, um dies zu tun.
quelle
Antworten:
Ich verwende diese Lokalisierungsmethode und füge einen Routenparameter hinzu, der die Kultur und Sprache festlegt, wenn ein Benutzer example.com/xx-xx/ besucht.
Beispiel:
Ich habe einen Filter, der die eigentliche Kultur- / Spracheinstellung vornimmt:
Um das Internationalisierungsattribut zu aktivieren, fügen Sie es einfach Ihrer Klasse hinzu:
Immer wenn ein Besucher zu http://example.com/de-DE/Home/Index geht, wird die deutsche Website angezeigt.
Ich hoffe, diese Antwort weist Sie in die richtige Richtung.
Ich habe auch ein kleines MVC 5-Beispielprojekt erstellt, das Sie hier finden
Gehen Sie einfach zu http: // {yourhost}: {port} / de-de / home / index, um das aktuelle Datum in Englisch (USA) anzuzeigen, oder ändern Sie es in http: // {yourhost}: {port} / de -de / home / index für deutsch etcetera.
quelle
Ich weiß, dass dies eine alte Frage ist, aber wenn Sie wirklich möchten, dass dies mit Ihrem ModelBinder funktioniert (sowohl in Bezug auf
DefaultModelBinder.ResourceClassKey = "MyResource";
die in den Datenanmerkungen der viewmodel-Klassen angegebenen Ressourcen), ist der Controller oder sogar einActionFilter
zu spät Stellen Sie die Kultur ein .Die Kultur könnte
Application_AcquireRequestState
zum Beispiel gesetzt werden:BEARBEITEN
Tatsächlich gibt es einen besseren Weg, einen benutzerdefinierten Routehandler zu verwenden, der die Kultur gemäß der URL festlegt, die Alex Adamyan in seinem Blog perfekt beschrieben hat .
Alles was zu tun ist, ist die
GetHttpHandler
Methode zu überschreiben und die Kultur dort festzulegen.quelle
Ich würde es im Initialize-Ereignis des Controllers so machen ...
quelle
Da es sich um eine Einstellung handelt, die pro Benutzer gespeichert wird, ist die Sitzung ein geeigneter Ort zum Speichern der Informationen.
Ich würde Ihren Controller so ändern, dass die Kulturzeichenfolge als Parameter verwendet wird, anstatt für jede potenzielle Kultur eine andere Aktionsmethode zu verwenden. Das Hinzufügen eines Links zur Seite ist einfach und Sie sollten nicht immer denselben Code schreiben müssen, wenn eine neue Kultur erforderlich ist.
quelle
Was ist der beste Ort ist Ihre Frage. Der beste Platz befindet sich in der Controller.Initialize- Methode. MSDN schreibt, dass es nach dem Konstruktor und vor der Aktionsmethode aufgerufen wird. Im Gegensatz zum Überschreiben von OnActionExecuting können Sie durch Platzieren Ihres Codes in der Initialize-Methode alle benutzerdefinierten Datenanmerkungen und -attribute für Ihre Klassen und Ihre zu lokalisierenden Eigenschaften nutzen.
Meine Lokalisierungslogik stammt beispielsweise aus einer Klasse, die in meinen benutzerdefinierten Controller eingefügt wird. Ich habe Zugriff auf dieses Objekt, da Initialize nach dem Konstruktor aufgerufen wird. Ich kann die Kulturzuweisung des Threads durchführen und nicht jede Fehlermeldung korrekt anzeigen lassen.
Auch wenn sich Ihre Logik nicht in einer Klasse wie dem von mir bereitgestellten befindet, haben Sie Zugriff auf den RequestContext, mit dem Sie die URL und den HttpContext sowie die RouteData verwenden können, mit denen Sie grundsätzlich jede mögliche Analyse durchführen können.
quelle
Wenn Sie Subdomains verwenden, z. B. "pt.mydomain.com", um beispielsweise Portugiesisch festzulegen, funktioniert die Verwendung von Application_AcquireRequestState nicht, da sie bei nachfolgenden Cache-Anforderungen nicht aufgerufen wird.
Um dies zu lösen, schlage ich eine Implementierung wie diese vor:
Fügen Sie den VaryByCustom-Parameter wie folgt zum OutPutCache hinzu:
Rufen Sie in global.asax.cs die Kultur mithilfe eines Funktionsaufrufs vom Host ab:
Fügen Sie die Funktion GetCultureFromHost zu global.asax.cs hinzu:
Und schließlich überschreiben Sie GetVaryByCustomString (...), um auch diese Funktion zu verwenden:
Die Funktion Application_AcquireRequestState wird bei nicht zwischengespeicherten Aufrufen aufgerufen, wodurch der Inhalt generiert und zwischengespeichert werden kann. GetVaryByCustomString wird bei zwischengespeicherten Aufrufen aufgerufen, um zu überprüfen, ob der Inhalt im Cache verfügbar ist. In diesem Fall untersuchen wir erneut den Wert der eingehenden Hostdomäne, anstatt uns nur auf die aktuellen Kulturinformationen zu verlassen, die sich für die neue Anforderung möglicherweise geändert haben (weil wir verwenden Subdomains).
quelle
1: Erstellen Sie ein benutzerdefiniertes Attribut und überschreiben Sie die Methode wie folgt:
2: Suchen Sie in App_Start nach FilterConfig.cs und fügen Sie dieses Attribut hinzu. (Dies funktioniert für die gesamte Anwendung)
Das ist es !
Wenn Sie anstelle der gesamten Anwendung eine Kultur für jeden Controller / jede Aktion definieren möchten, können Sie dieses Attribut wie folgt verwenden:
Oder:
quelle
quelle