2016-04-29 29 views
7

Sto provando a reindirizzare l'utente a sottodominio in base alla sua posizione di indirizzo IP. Ho un osservatore di caricamento della pagina che esegue una funzione su ogni richiesta e ottiene la posizione dell'utente e quando provo a reindirizzare su un altro dominio mi dà l'errore "Troppi reindirizzamenti" e non riesco a trovare un modo per risolvere questo problema .Reindirizzare Utente a sottodominio basato su IP

Attualmente il mio codice è simile come segue

string CountryName = ""; 
var Country = HttpContext.Current.Response.Cookies["Country"]; 
Country.Expires = DateTime.Now.AddDays(365); 
var ip = HttpContext.Current.Request.UserHostAddress; 

if (!string.IsNullOrEmpty(ip) && ip != null && ip != "127.0.0.1") 
{ 
    using (var client = new WebServiceClient(xxxxx, "xxxxxxxx")) 
    { 
     var IpCountry = client.Country(ip); 
     CountryName = IpCountry.Country.Name; 
    } 
    switch (CountryName) 
    { 
     case "Denmark": 
      if (Country.Value != CountryName) 
      { 
       Country.Value = CountryName; 
       HttpContext.Current.Response.Redirect("/"); 
      } 
      break; 
     case "United Kingdom": 
      if (Country.Value != CountryName) 
      { 
       Country.Value = CountryName; 
       HttpContext.Current.Response.Redirect("/en"); 
      } 
      break; 
     case "Germany": 
      if (Country.Value != CountryName) 
      { 
       Country.Value = CountryName; 
       HttpContext.Current.Response.Redirect("/de"); 
      } 
      break; 
     case "Sweden": 
      if (Country.Value != CountryName) 
      { 
       Country.Value = CountryName; 
       HttpContext.Current.Response.Redirect("/se"); 
      } 
      break; 
     case "Norway": 
      if (Country.Value != CountryName) 
      { 
       Country.Value = CountryName; 
       HttpContext.Current.Response.Redirect("/no"); 
      } 
      break; 
     default: 
      if (Country.Value != CountryName) 
      { 
       Country.Value = CountryName; 
       //HttpContext.Current.Response.Redirect("http://www.google.com"); 
      } 
      break; 
    } 
} 
else if (loadedArgs.pageview.Area.ID != 2) 
{ 
    HttpContext.Current.Response.Redirect("/choose-country"); 
} 

ulteriormente più mi piacerebbe anche sapere che cosa potrebbe essere altri modi possibili per gestire questo scenario in altro modo migliore in modo tale codice non vengono eseguiti su ogni pagina caricare una volta impostati i cookie. Molte grazie in anticipo.

+0

Vuoi dire che quando disattivi reindirizza a google stai ricevendo errore in molti reindirizzamenti? –

+0

@VolodymyrBilyachat No, Quando commento tutti i reindirizzamenti funziona benissimo altrimenti mi dà errore Troppi reindirizzamenti. che però ha senso visto che questo codice gira sul caricamento della pagina e, dopo averlo reindirizzato, esegue nuovamente il codice ed entra in un ciclo infinito. Quindi voglio capire come prevenirlo? –

+0

Dove stai attualmente impostando un cookie con il nome del paese? – Evk

risposta

0

è possibile utilizzare il codice riportato di seguito per ottenere l'indirizzo IP del client. vale a dire, l'indirizzo IP della macchina che ha richiesto una pagina nel tuo sito web.

String UserIP = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; 
if (string.IsNullOrEmpty(UserIP)) 
{ 
    UserIP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; 
} 

Di seguito è riportato il formato che è necessario utilizzare per l'URL dell'API.

freegeoip.net/{format}/{IP_or_hostname} 

formato -> è il formato di output di risposta. Potrebbe essere CSV o XML o JSON.

Per esempio, se vogliamo ottenere la risposta in formato JSON quindi abbiamo potuto utilizzare l'URL API come 'http://freegeoip.net/json/clientIPAddress_here'

string url = "http://freegeoip.net/json/" + UserIP.ToString(); 
WebClient client = new WebClient(); 
string jsonstring = client.DownloadString(url); 

Per ottenere il formato di risposta di esempio, eseguire questo http://freegeoip.net/json/XX.XX.XX.XX (sostituire XX. XX.XX.XX con l'indirizzo IP richiesto) direttamente nel browser. Vedrai il formato di risposta sottostante.

{ 
"ip":"xxx.xxx.xxx.xxx", 
"country_code":"", 
"country_name":"", 
"region_code":"", 
"region_name":"", 
"city":"", 
"zip_code":"", 
"time_zone":"", 
"latitude":0, 
"longitude":0, 
"metro_code":0 
} 

Utilizzare il codice qui sotto per convertire la risposta a oggetto JSON e poi leggere i valori di oggetto JSON e salvare in una variabile di sessione o di qualche altra variabile.

dynamic dynObj = JsonConvert.DeserializeObject(jsonstring); 
System.Web.HttpContext.Current.Session["LocId"] = dynObj.country_code; 

Si può anche rilevare il paese utilizzando l'intestazione Location troppo Su HttpWebRequest è possibile impostare AllowAutoRedirect false per gestire il reindirizzamento da soli.

// don't allow redirects, they are allowed by default so we're going to override 
myRequest.AllowAutoRedirect = false; 

// send the request 
HttpWebResponse response = myRequest.GetResponse(); 

// check the header for a Location value 
if(response.Headers["Location"] == null) 
{ 
    // null means no redirect 
} 
else 
{ 
    // anything non null means we got a redirect 
} 

soluzione del problema "Troppi reindirizzamenti": loop di reindirizzamento è come una situazione in cui>"A indica B e B punti di nuovo ad un" . Tale reindirizzamento manterrà il browser in un ciclo infinito e la pagina web non verrà mai visualizzata. Nei vecchi tempi, tali reindirizzamenti o loop infiniti venivano utilizzati per generare un browser appeso. Fortunatamente, i browser moderni sono in grado di rilevare tali cicli di reindirizzamento e interrompono il ciclo visualizzando un messaggio di errore: "Errore 310 (net :: ERR_TOO_MANY_REDIRECTS): erano troppi reindirizzamenti ".

Questo problema può verificarsi a livello del client o del server. Se non esiste un ciclo di reindirizzamento sul lato server, è probabile che il problema venga risolto eliminando i cookie dal browser.

Quindi suggerisco di controllare il routeconfig.cs per tale percorso o il funzionamento di reindirizzamento simile che punta a se stesso dopo aver eliminato i cookie dal browser

Spero che questo aiuti :)

+0

Ciao, grazie per la tua risposta ma non risolve il mio problema. Il mio problema è con l'errore "Troppi reindirizzamenti" perché ho questo codice sulla pagina load observer che gira su ogni chiamata alla pagina, quindi dopo aver reindirizzato il codice viene eseguito di nuovo ed entra in loop infinito quindi la mia domanda di base è che come prevenirlo entrare nel ciclo infinito? –

+0

@UmarKhan Ho aggiornato la mia risposta per favore controlla la soluzione – Aminul

0

Credo che il problema sta nella logica che non identifica se la richiesta è prima o dopo il reindirizzamento. La sequenza sembra essere

The code executes once when a URL xyz.com 
The redirect to xyz.com/en happens 
Again the code executes and tries to redirect to xyz.com/en/en 

Questo può essere confermato con qualche debug.

suggerisco il codice dovrebbe eseguire e reindirizzare se l'URL viene richiesto non termina con "en" o "de" (la lista può essere mantenuta nell'applicazione)

Potrebbe essere necessario cambiare il modo in cui anche tu gestisci il tuo paese predefinito, perché se la logica non è un paese indica un paese predefinito, allora quello che ho menzionato sopra non funzionerà.

0

In Asp.Net MVC, ho una classe che gestisce indirizzi IP non validi e li reindirizza in base all'indirizzo IP. Io uso il seguente codice:

protected override async void HandleUnauthorizedRequest(AuthorizationContext context) 
     { 
      var ipAddress = HttpContext.Current.Request.UserHostAddress; 
      if (await IpAddressValid(ipAddress)) return; 
      var urlHelper = new UrlHelper(context.RequestContext); 
      var address = urlHelper.Action("InvalidIpRange", "Account"); 
      context.Result = new RedirectResult(address ?? "www.google.com"); 
     } 

     private async Task<bool> IpAddressValid(string ipAddress) 
     { 
      if (ipAddress == "::1") 
       return true; 
      var longIp = Ip2Int(ipAddress); 
      var addr = await GeoIPCountry.ReturnGeoIpCountries(longIp, longIp); //dbContext.GeoIPCountries.Where(x => x.Start >= longIp && x.End <= longIp); 
      return addr.All(g => g.CountryCode == "US"); 
     } 

     /// <summary> 
     /// Converts IP Address to Long Stack Space. 
     /// </summary> 
     /// <param name="ipAddress"></param> 
     /// <returns></returns> 
     public int Ip2Int(string ipAddress) 
     { 
      try 
      { 
       var addr = IPAddress.Parse(ipAddress); 
       uint ip = 
        (uint) IPAddress.NetworkToHostOrder((int) BitConverter.ToUInt32(addr.GetAddressBytes(), 0)); 
       return (int)ip; 
      } 
      catch (Exception) 
      { 
       return 0; 
      } 
     } 

Nella parte superiore di ciascun controller che lo richiede, tutto quello che dovete fare è aggiungere il flag [IpAddressAuthorize] e si occuperà di tutto. Questo accade prima di ogni altra azione, quindi se dovessi essere in grado di modificarlo abbastanza facilmente.

1

Non ho accesso al tuo codice, ma, se sto leggendo il tuo codice, la correzione per il problema di reindirizzamento è controllare l'esistenza dei cookie prima di qualsiasi logica di creazione/reindirizzamento. Ho apportato alcune modifiche, ti preghiamo di provare e fammi sapere di eventuali problemi.

var context = HttpContext.Current; 
var cookieName = "Country"; 
var ip = context.Request.UserHostAddress; 

if (!string.IsNullOrWhiteSpace(ip) && ip != "127.0.0.1") 
{ 
    //If the cookie is present (means cookie is set already) then return 
    if (context.Request.Cookies[cookieName] != null) 
    { 
     return; 
    } 

    string countryName; 

    using (var client = new WebServiceClient(xxxxx, "xxxxxxxx")) 
    { 
     var ipCountry = client.Country(ip); 
     countryName = ipCountry.Country.Name; 
    } 

    context.Response.Cookies.Add(new HttpCookie(cookieName) 
    { 
     Value = countryName, 
     Expires = DateTime.Now.AddDays(365) 
    }); 

    switch (countryName) 
    { 
     case "Denmark": 
      context.Response.Redirect("/"); 
      break; 
     case "United Kingdom": 
      context.Response.Redirect("/en"); 
      break; 
     case "Germany": 
      context.Response.Redirect("/de"); 
      break; 
     case "Sweden": 
      context.Response.Redirect("/se"); 
      break; 
     case "Norway": 
      context.Response.Redirect("/no"); 
      break; 
     default: 
      //context.Response.Redirect("http://www.google.com"); 
      break; 
    } 
} 
else if (loadedArgs.pageview.Area.ID != 2) 
{ 
    context.Response.Redirect("/choose-country"); 
} 

Grazie, Soma.

0

Non si forniscono molte informazioni sull'osservatore che viene eseguito su ogni richiesta, ma se viene eseguito su ogni richiesta, verrà semplicemente eseguito di nuovo quando si reindirizza l'utente dopo aver controllato il proprio paese.

Per eseguire il debug di questo, è sufficiente posizionare i breakpoint ovunque si chiami un reindirizzamento e controllare quale viene ripetutamente chiamato.

Per esempio, diciamo che l'utente è dalla Danimarca, nel qual caso si

context.Response.Redirect("/"); 

Ma questo farà sì che il 'osservatore' a correre e reindirizzare di nuovo! Quindi è necessario verificare se il reindirizzamento è già avvenuto inserendo un altro cookie o controllando se la pagina richiesta è già una pagina specifica della lingua e quindi non è necessario reindirizzare nuovamente.