2015-12-04 11 views
5

Sto lavorando su un sito MVC con più traduzioni. Stiamo cercando di farlo attraverso sottodomini come http://en.domain.com o http://fr.domain.com. Vogliamo anche supportare il dominio regolare http://domain.com.Ottieni sottodominio in MVC per l'internazionalizzazione

Le traduzioni funzionano purché si modifichi manualmente il sottodominio, ma sto cercando un modo per automatizzarlo e mantenere l'intero URL corrente per consentire a un utente che trova http://en.domain.com/product di fare clic sul collegamento e ottenere un'altra versione della lingua di la stessa pagina. Sembra semplice isolare il sottodominio se esiste, eliminarlo dall'url corrente e sostituirlo con la versione della lingua specificata.

In sostanza:

http://en.domain.com/product (originale)

http://domain.com/product (pulite)

http://fr.domain.com/product o http://de.domain.com/product ecc ... (uscita)

ho iniziato alla ricerca di costruito in funzionalità come Request.Url.Subdomain ma hai concluso che non esiste una creatura magica del genere. Poi passai alla manipolazione delle stringhe di base, ma sembrava davvero convuluto, quindi partii per trovare una soluzione regex.

Ho provato questo regex con alcuni regex tester online che normalmente funzionano per me e stanno identificando correttamente il sottodominio quando esiste, ma non riesce a trovare un risultato quando il codice viene effettivamente eseguito.

Io uso solo le espressioni regolari un po 'e spero che ci sia qualcosa di veramente ovvio che sto sbagliando qui. Se c'è una soluzione migliore sono aperto ad altre implosioni.

C#

string url = Request.Url.AbsoluteUri; //http://en.domain.com/ 
Regex regex = new Regex(@"/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/", RegexOptions.IgnoreCase); 
GroupCollection results = regex.Match(url).Groups; 
Group result = results[0]; 

ecco la soluzione che ho per ora. Non elegante come vorrei, ma per qualcosa che ha mangiato troppo tempo, ora funziona come previsto.

View

<a href="@Html.Action("ChangeLanguage", new { lang = "en" })">English</a> 
<a href="@Html.Action("ChangeLanguage", new { lang = "fr" })">French</a> 

azione

public string ChangeLanguage(string controller, string lang) 
    { 
     string url = Request.Url.AbsoluteUri; 

     Regex regex = new Regex(@"(?:https*://)?.*?\.(?=[^/]*\..{2,5})", RegexOptions.IgnoreCase); 
     GroupCollection results = regex.Match(url).Groups; 
     Group result = results[0]; 
     if (result.Success) 
     { 
      string[] resultParts = result.Value.Split('/'); 
      string newSubDomain = resultParts[0] + "//" + lang + "."; 
      url = url.Replace(result.Value, newSubDomain); 
     } 
     else 
     { 
      string[] urlParts = url.Split('/'); 
      string oldParts = urlParts[0] + "//"; 
      string newParts = urlParts[0] + "//" + lang + "."; 
      url = url.Replace(oldParts, newParts); 
     } 


     return url; 
    } 
+1

cosa ovvia: non avete bisogno di delimitatori regex in C#. Prova '@" (?: Https *: //)?. *? \. (? = [^ /] * \ .. {2,5}) '. –

+0

Hai considerato di utilizzare qualcosa di diverso dai sottodomini? Http : // domain.com/fr/product' funziona altrettanto bene, e non richiede ogni nuova "traduzione" per essere registrato come voce DNS –

+0

@stribizhev Questo è tutto io non sono sicuro al 100% perché il.. parte centrale funziona, ma sembra dai test –

risposta

2

usare qualcosa di simile alla seguente (psuedocodarlo - dovrebbe aggiungere i controlli di sicurezza e simili):

Uri myHost = new Uri("https://en.mydomain.com"); 
string hostname = myHost.Host; // returns en.mydomain.com 
string subdomain = string.split(".", hostname)[0]; // subdomain = "en" 

Questo otterrà gli hos tname, che puoi dividere su "." a un array e prendi il primo elemento.

MODIFICA: collegamento a documenti MSDN su Uri.Host

https://msdn.microsoft.com/en-us/library/system.uri.host(v=vs.110).aspx

+0

Questo è essenzialmente quello che stavo cercando in un primo momento, ma ho bisogno di una soluzione che non richiede un dominio "stringa magica" per essere inseriti. E 'una cosa abbastanza comune per qualcuno in una posizione di marketing da qualche parte per pubblicare un URL con materiale stampato o legale e basta "scegliere" un dominio per questo. Ciò significa che spesso non abbiamo scelta ma per supportare più domini per lo stesso sito. –

+1

Questo non richiede alcuna stringa magica. Il parametro del costruttore Uri nell'esempio potrebbe provenire da qualsiasi cosa, inclusa una proprietà di richiesta, un file di configurazione, ecc. Ho appena usato un letterale lì per brevità. La parte importante è che la proprietà Uri.Host restituisce il nome del dominio senza le altre "cose" in esso, e se, per convenzione, la lingua è sempre la prima, allora puoi dividere il punto e prendere il primo elemento, o cercare la matrice per un modello. Le persone di marketing hanno un'incredibile capacità di infrangere qualsiasi codice, indipendentemente da come lo fai. – DVK

3

È possibile utilizzare il routing personalizzato per rendere più semplice

routes.Add("LanguageRoute", new DomainRoute( 
"{language}.example.com/{controller}/{action}", // Domain with parameters 
"{controller}/{action}/{id}", // URL with parameters 
new { controller = "Home", action = "Index", id = "" } // Parameter defaults 

))

E ottenere il valore della lingua sul controller

public ActionResult Index(string language) 
    { 
     return View(); 
    } 

un link utile può aiuto per voi: http://benjii.me/2015/02/subdomain-routing-in-asp-net-mvc/

+0

Questo è il tipo di soluzione che vorrei utilizzare, ma io non capisco l'uso del l'override RouteBase nel link perché posso vedere che è in esecuzione e l'aggiornamento del percorso, ma sta accadendo dopo l'azione corre quindi il parametro action è sempre nullo. Presumo che abbia qualcosa a che fare con il metodo GetVirtualPath che resta da implementare, ma non l'abbiamo ancora capito. –

+0

Hey Locke ho appena campionato il codice come utilizzo di base. Ho bisogno di dormire ma ti darò un esempio funzionante con la modifica di domani. Spero che funzioni per te. – c0demaster

+0

Certo, questo è più di quanto potrei davvero chiedere. Nel frattempo ho intenzione di continuare a provare. –

0

Facciamo qualcosa di simile su uno dei miei progetti, e questo è come ottenere il sottodominio corrente:

string GetSubDomain(Uri url, string defaultValue) 
{ 
    string subdomain = defaultValue; 

    if (url.HostNameType == UriHostNameType.Dns) 
    { 
     string host = url.Host; 
     if (host.Split('.').Length > 2) 
     { 
      int index = host.IndexOf("."); 
      int lastIndex = host.LastIndexOf("."); 
      subdomain = index.Equals(lastIndex) ? defaultValue : host.Substring(0, index); 
     } 
    } 

    return subdomain; 
} 

si può usare in questo modo:

var subdomain = GetSubDomain(HttpContext.Current.Request.Url, "en"); 

Questo presuppone che solo tu mai volere la prima sottodominio nell'URL corrente, in modo che entrambi http://fr.example.com e http://fr.something.example.com sarebbe cedere fr, mentre http://example.com sarebbe cedere en (il valore di default in questo esempio).

Problemi correlati