Redirecting a user to a subdomain by IP

I am trying to redirect a user to a subdomain based on his IP address location. I have a page load observer that runs a function for each request and gets the user's location, and when I try to redirect to another domain, it gives me the error "Too many redirects" and I can’t find a way to solve this problem.

Currently my code is as follows

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"); } 

Further, I would also like to know what other possible ways of solving this scenario could be more effective, therefore this code does not run every time the page loads after cookies are set. Thank you very much in advance.

+7
redirect c # response.redirect
source share
5 answers

I do not have access to your code, but if I read your code, the fix for the redirect problem is to check if cookies exist before any creation / redirection logic. I made some changes, please try and let me know about any problems.

 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"); } 

Thanks, Soma.

+1
source share

You can use the code below to get the client IP address. that is, the IP address of the machine that requested the page on your website.

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

Below is the format to use for the API URL.

 freegeoip.net/{format}/{IP_or_hostname} 
Format

-> is the response output format. It can be CSV or XML or JSON.

For example, if we want to get a response in JSON format, we could use the API URL as http://freegeoip.net/json/clientIPAddress_here '

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

To get a sample response, run http://freegeoip.net/json/XX.XX.XX.XX (replace XX.XX.XX.XX with the required ip address). right in the browser. You will see the following response format.

 { "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 } 

Use the code below to convert the response to a JSON object and then read the values ​​of the JSON object and save it in a session variable or some other variable.

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

You can also discover the country using the Location header. On HttpWebRequest you can set AllowAutoRedirect to false to handle the redirection yourself.

 // 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 } 

Solving the “Too many redirects” problem: The redirect cycle is similar to the situation where> “A points to B and B points to A” . Such redirection will support the browser in an infinite loop, and the web page will never be displayed. In the old days, such redirects or endless loops used to create a freezing browser. Currently, modern browsers are capable of detecting such redirection loops, and they break the loop causing the error message: "Error 310 (net :: ERR_TOO_MANY_REDIRECTS): there were too many redirects."

This problem can be caused either on the client side or on the server. If there is no redirect loop on the server side, the problem is likely to be solved only by deleting cookies from the browser.

Therefore, I suggest checking your routeeconfig.cs for such a route or a similar redirect operation that points to itself after deleting cookies from the browser

Hope this helps :)

0
source share

I think the problem is the logic, which does not determine if the request is before or after the redirect. It seems that the sequence

 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 

This can be confirmed by another debug.

I suggest that your code be executed and redirected if the requested URL does not end with "en" or "de" (the list may be supported in the application)

You may need to change the way your default country is processed, because if the logic does not indicate the default country, then what I mentioned above will not work.

0
source share

In Asp.Net MVC, I have a class that processes invalid IP addresses and redirects them based on the IP address. I am using the following code:

 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; } } 

At the top of every controller that requires this, all you have to do is add the [IpAddressAuthorize] flag and it will handle everything. This happens before any other action, so if you can easily modify it.

0
source share

You do not provide much information about the “observer that runs on each request”, but if it is actually executed for each request, it will simply start again when you redirect the user after checking your country.

To debug this, simply place breakpoints wherever you call the redirect, and check which one is called repeatedly.

For example, let's say that the user is from Denmark, in which case you

 context.Response.Redirect("/"); 

But it will force your "observer" to start and redirect again! Therefore, you need to check if the redirect has occurred by placing another cookie or checking if the requested page is already a language page, and therefore there is no need to redirect again.

0
source share

All Articles