Optional Überschreiben der Anforderungskultur über URL / Route in einer ASP.NET Core 1.0-Anwendung

8

Ich versuche, die Kultur der aktuellen Anfrage zu überschreiben. Ich habe es funktioniert teilweise mit einem benutzerdefinierten ActionFilterAttribute .

%Vor%

Auf dem Controller verwende ich LanguageActionFilter .

%Vor%

Das funktioniert soweit, aber ich habe zwei Probleme damit:

  1. Ich mag es nicht, {culture} auf jedem Controller deklarieren zu müssen, da ich ihn auf jeder Route brauche.
  2. Ich habe eine Standardkultur, die mit diesem Ansatz nicht funktioniert, auch wenn ich sie aus offensichtlichen Gründen als [Route("api/{culture=en-US}/[controller]")] deklariere.

Das Festlegen eines Standardroutergebnisses funktioniert auch nicht.

%Vor%

Ich habe auch in einer benutzerdefinierten IRequestCultureProvider -Implementierung untersucht und sie der UseRequestLocalization -Methode wie

hinzugefügt %Vor%

aber dann habe ich keinen Zugang zu den Routen dort (ich nehme an, weil die Routen später in der Pipeline gemacht werden). Natürlich könnte ich auch versuchen, die angeforderte URL zu parsen. Und ich weiß nicht einmal, ob ich die Route an diesem Ort ändern könnte, so dass es mit der Kultur in der obigen Route übereinstimmt.

Das Übergeben der Kultur über Abfrageparameter oder das Ändern der Reihenfolge der Parameter innerhalb der Route ist keine Option.

Sowohl die URLs api/en-us/products als auch api/products sollten an denselben Controller weitergeleitet werden, wobei die ersten die Kultur nicht ändern.

Die Reihenfolge, in der die Kultur bestimmt wird, sollte

sein
  1. Wenn in URL definiert, nimm es
  2. Wenn nicht in URL definiert, überprüfen Sie Abfragezeichenfolge und verwenden Sie
  3. Falls nicht in der Abfrage definiert, überprüfen Sie die Cookies
  4. Falls nicht in Cookie definiert, verwenden Sie Accept-Language header.

2-4 erfolgt über UseRequestLocalization und das funktioniert. Außerdem mag ich nicht, dass der aktuelle Ansatz zwei Attribute zu jedem Controller hinzufügen muss ( {culture} in route und [ServiceFilter(typeof(LanguageActionFilter))] ).

Bearbeiten: Ich möchte auch die Anzahl der gültigen Gebietsschemas auf die in SupportedCultures -Eigenschaft der RequestLocalizationOptions , die an die UseRequestLocalization übergeben wurde, festgelegte Anzahl beschränken.

IOptions<RequestLocalizationOptions> localizationOptions in LanguageActionFilter funktioniert nicht, da es eine neue Instanz von RequestLocalizationOptions zurückgibt, wobei SupportedCultures immer null ist und nicht die an die übergebene.

FWIW es ist ein RESTful WebApi Projekt.

    
Tseng 06.03.2016, 16:31
quelle

1 Antwort

18

Aktualisieren Sie ASP.Net Core 1.1

Ein neues RouteDataRequestCultureProvider kommt als Teil des 1.1 release , was hoffentlich bedeutet, dass Sie keinen eigenen Anfragehersteller mehr erstellen müssen. Möglicherweise finden Sie die Informationen hier noch nützlich (wie die Routing-Bits) oder Sie sind möglicherweise an der Erstellung eines eigenen Anforderungskulturanbieters interessiert.

Sie können zwei Routen erstellen, mit denen Sie auf Ihre Endpunkte mit und ohne ein Kultursegment in der URL zugreifen können. Sowohl /api/en-EN/home als auch /api/home werden an den Home-Controller weitergeleitet. (So ​​wird /api/blah/home nicht mit der Route mit Kultur übereinstimmen und wird 404 erhalten, da der Blah-Controller nicht existiert)

Damit diese Routen funktionieren, hat die eine, die den culture-Parameter enthält, eine höhere Präferenz und der culture-Parameter eine regex:

%Vor%

Die obigen Routen funktionieren mit dem MVC-Stil-Controller, aber wenn Sie eine Ruhe-Schnittstelle mit WB-Api-Stil von Controllern erstellen, ist das Attribut-Routing der bevorzugte Weg in MVC 6.

  • Eine Option ist die Verwendung von Attribut-Routing, aber verwenden Sie eine Basisklasse für all Ihre API-Controller, wo Sie die Basissegmente der URL festlegen können:

    %Vor%
  • Eine schnelle Möglichkeit, die Basisklasse zu vermeiden, ohne zu viel benutzerdefinierten Code zu benötigen, ist die Web-API-Kompatibilität shim :

    • Fügen Sie das Paket "Microsoft.AspNet.Mvc.WebApiCompatShim": "6.0.0-rc1-final" hinzu
    • Fügen Sie die Shim-Konventionen hinzu:

      %Vor%
    • Stellen Sie sicher, dass Ihre Controller von ApiController erben, was vom shim-Paket
    • hinzugefügt wird
    • Definieren Sie die Routen einschließlich des culture-Parameters mit der MapApiRoute-Überladung:

      %Vor%
  • Die sauberere und bessere Option wäre das Erstellen und Anwenden Ihrer eigenen IApplicationModelConvention , die darauf achtet, den Attributrouten das Kulturpräfix hinzuzufügen. Dies ist für diese Frage nicht möglich, aber ich habe die Idee für diesen Artikel zur Lokalisierung

Dann müssen Sie ein neues IRequestCultureProvider erstellen, das sich die Anfrage-URL ansieht und die Kultur von dort extrahiert (falls vorhanden).

  

Nach dem Upgrade auf ASP .Net Core 1.1 vermeiden Sie möglicherweise die manuelle Analyse der Anfrage-URL und das Extrahieren des Kultursegments.

     

Ich habe die Implementierung von RouteDataRequestCultureProvider in ASP.Net Core 1.1, und sie verwenden eine HttpContext-Erweiterungsmethode GetRouteValue(string) zum Abrufen von URL-Segmenten innerhalb des Anforderungsanbieters:

%Vor%      

Ich vermute jedoch (ich hatte noch keine Gelegenheit, es noch zu versuchen), dass dies nur funktioniert, wenn Middleware als MVC-Filter . Auf diese Weise läuft Ihre Middleware nach der Routing-Middleware, die die IRoutingFeature in den HttpContext hinzufügt. Als einen schnellen Test, das Hinzufügen der folgenden Middleware vor UseMvc erhalten Sie keine Route Daten:

%Vor%

Um das neue IRequestCultureProvider zu implementieren, müssen Sie nur:

  • Suchen Sie nach dem culture-Parameter im Pfad der Anfrage-URL.
  • Wenn kein Parameter gefunden wird, gebe null zurück. (Wenn alle Anbieter null zurückgeben, wird die Standardkultur verwendet)
  • Wenn ein Kulturparameter gefunden wird, geben Sie ein neues ProviderCultureResult mit dieser Kultur zurück.
  • Die Lokalisierungs-Middleware wird auf den Standard 1, wenn es sich nicht um eine der unterstützten Kulturen handelt.

Die Implementierung sieht so aus:

%Vor%

Aktivieren Sie abschließend die Lokalisierungsfunktionen einschließlich Ihres neuen Anbieters als erste in der Liste der unterstützten Anbieter. Da sie in der richtigen Reihenfolge ausgewertet werden und die erste, die ein Nicht-Null-Ergebnis zurückgibt, gewinnt, wird Ihr Provider Vorrang haben und als nächstes kommt die Standardnamen (Abfragezeichenfolge, Cookie und Header).

%Vor%     
Daniel J.G. 13.03.2016, 13:13
quelle