Geografisk lokalisering i ASP.NET

Relaterede dokumenter
Geografisk lokalisering i JSP

Parameters. Denne artikel beskriver hvorfor parameters er gode. Den forudsætter lidt kendskab til C# og ADO.NET.

Skrevet den 18. Feb 2010 af arne_v I kategorien Programmering / Visual Basic.NET

RMI introduktion. Denne artikel beskriver Java RMI (Remtote Method Invocation).

Introduction til.net remoting i VB.NET

Prepared Statements. Denne artikel beskriver hvorfor prepared statements er gode. Den forudsætter lidt kendskab til Java og JDBC.

Den forudsætter kendskab til XML og VB.NET men ikke til brug af XML i VB.NET.

Den forudsætter kendskab til XML og C# men ikke til brug af XML i C#.

Database design for begyndere

Introduction til.net remoting i C#

Undtagelseshåndtering i C#

Singleton pattern i C#

Send fra Java. Denne artikel fortæller hvad man skal bruge og hvordan man skal kode for at sende fra Java.

Tilfældige tal. Denne artikel introducerer generering af tilfældige tal og viser lidt om hvad man kan og ikke mindst hvad man ikke bør bruge.

Tredjepart webservices

Singleton pattern i Java

1B fil database. //globale variabler DateTime tid; // erklærer en variabel af typen datetime DateTime dag; // erklærer en variabel af typen datetime

Som sagt kræves der helst lidt viden om OOP hvis man virkelig vil lærer noget, og ikke bare lave copypaste

//Udskriver System.out.println("Hej " + ditfornavn + " " + ditefternavn + "."); System.out.println("Du er " + dinalder + " aar gammel!

Listen over reserverede ord er meget lang, men de væsentligste vil jeg beskrive her i denne artikel:

I chartkontrollen er der så mange muligheder, at vi her blot vil se på nogle ganske enkle.

Den forudsætter kendskab til C++ og lidt kendskab til SQL og MySQL C API.

Hvordan vælger jeg dokumentprofilen?

Bits, bit operationer, integers og floating point

I denne artikel vil vi bruge en User klasse som vi så vil gruppere på forskellige måder.

RMI avanceret. Denne artikel beskriver nogle mere avancerede features i RMI. Den gør det muligt at lave mere realistiske applikationer.

Ratingsystem i PHP og MySQL

Introduktion til SQL queries

Derfor vil jeg bygge dette eksempel på een table hvor der kan tilkyttes personer til ALLE noder og der kan tilføjes et vilkårligt antal niveauer

Test med JUnit 3. Denne artikel introducerer JUnit 3. Den forklarer ideen med JUnit. Og den viser hvordan man konkret bruger det.

.NET 4.5 og C# 5.0. Denne artikel beskriver nogle af de nye features i.net 4.5 og C# 5.0. Den forudsætter et vist kendskab til.net og C#.

Arkitektur for begyndere

Dynamiske Billeder, Image Map & XY coordinater. ASP.NET og Access Databasen.

SAX Simple API for XML.

Threads i Java. Denne artikel giver en introduktion til threads i Java. Den beskriver hvad tråde er og forklarer hvordan de bruges i Java

Test med NUnit. Denne artikel introducerer NUnit. Den forklarer ideen med NUnit. Og den viser hvordan man konkret bruger det.

I profil-feltet kan imastra-kunder vælge om upload skal ske ligesom filerne var indsendt til mailboksen eller

Databaseadgang fra Java

Værktøjer fra værktøjskassen. Søren Breddam, Stevns Kommune

I denne artikel vil jeg gennemgå hvordan en side for RSS "Live Bogmærke" kan se ud.

Hvad er Objekter - Programmering

Indhold. Senest opdateret:03. september Side 1 af 8

.NET 2.0 og C# 2.0. Denne artikel viser hvordan man kan bruge nogle af de nye features i.net 2.0 og C# 2.0. Det er ikke en komplet oversigt.

Anvendelse af metoder - Programmering

Indhold. Senest opdateret : 30. juli Side 1 af 5

Løsning af skyline-problemet

Tagwall med Php & MySQL

applikation----x----odbc driver manager----foobar ODBC driver----foobar database

Med register_globals = On får du automatisk adgang til en række variabelnavne i dit script.

Hvilket sprog er hurtigst

Database tips. Den forudsætter lidt kendskab til SQL men er for mindre erfarne. Denne guide er oprindeligt udgivet på Eksperten.dk

MySQL i Java. Tutorial lavet af Jákup W. Hansen TSU semester 05.januar 2007

Forskellige Java versioner

MySQL C API. Denne artikel beskriver hvordan man bruger MySQL C API. Der er beskrivelse af build med forskellige compilere.

Denne artikel gennemgår kort nogle mulighederne for brug af XML i ASP. Det sker ved brug af eksempler. Eksemplerne vil være i VBS.

Introduktion til funktioner, moduler og scopes i Python

I mit script tager jeg højde for det problem ved, at gemme et unikt tal mellem 0-9 på 6 cifre og derved vil de så blive vist som 2 online.

Indholdsfortegnelse Databaser og PHP... 3 Opgave... 4 Opgave... 5 Opgave... 6 Sidste opgave er en lille gæstebog... 7 Kilder og nyttige links:...

PROGRAM. using System; using System.Collections.Generic; using System.Text; using System.Collections;

Offset til terminalskærm i Java

WINDOWS FORMS EVENTS INTERAGEREN MED FIL SYSTEMET. Grundlæggende programmering Lektion 9

Java Klasse nedarvninger

Bootstrap Tutorial LAV EN SIMPEL RESPONSIVE SIDE MED BOOTSTRAP MATHIAS HERSKIND GROTRIAN

Endnu mere om tilfældige tal

Hosted CRM Outlook client connector setup guide. Date: Version: 1. Author: anb. Target Level: Customer. Target Audience: End User

Afsending af s vha. ASP

Forskellige databaser

Abstrakte datatyper C#-version

Koden i denne guide vil kun virke i Flash MX 2003 og MX ikke ældre versioner!

XML parsning i Java. Denne artikel beskriver hvordan man parser XML i Java. Den beskriver W3C DOM, SAX og JDOM.

Udvikling af DOTNET applikationer til MicroStation i C#

I denne artikel vil du ved hjælp af arrays kunne afrunde et decimaltal til et helt tal.

Introduktion til NAnt

SAX Simple API for XML.

Logging i Java. Den forudsætter kendskab til Java og noget generel udviklings erfaring. Denne guide er oprindeligt udgivet på Eksperten.

Java web applikationer med Tomcat

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 3

Delphi - CrackMe og Keygen

Dynamisk PHP design OPDATERET

Hosted CRM Outlook client connector setup guide. Date: Version: 1. Author: anb. Target Level: Customer. Target Audience: End User

I denne artikel, vil der blive gennemgået de grundlæggende PHP-funktioner, såsom udskrift til skærmen, tid og dato og if-sætningen.

Database programmerings tips

Sektornet VPN. Opsætning af Novell 4.1x server og klient på. Windows 2000/NT/XP

Kontrol-strukturer i PHP

Nye Java XML API'er

Uploade billeder eller andre filer ved hjælp af php og mysql

Tech College Aalborg. HomePort. Projekt Smart Zenior Home Guide til udvikling af nye adaptere til HomePort

Dokumentering af umbraco artikeleksport:

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 4

DM01 DM Obl. Afl. Jacob Christiansen, , D12, Elias 13/ Side 1 af 7

Exceptions i Delphi. Try except

Brugerdefineret menuer i Access

Register-databasen med.net

Upload af billeder/filer for nybegyndere Del. 2

BRP Kursusintroduktion og Java-oversigt

Eksempel: Skat i år 2000

GEONIS Vand. fact sheet. Planlæg, dokumentér og vedligehold

University of Southern Denmark Syddansk Universitet. DM503 Forelæsning 11

Øvelse 9. Klasser, objekter og sql-tabeller insert code here

Loginsystem (med MySQL)

Transkript:

Denne guide er oprindeligt udgivet på Eksperten.dk Geografisk lokalisering i ASP.NET Denne artikel forklarer lidt om hvorfor og hvordan man laver geografisk lokalisering og viser noget kode. Der er andre artikler for andre web sprog. Den forudsætter lidt kendskab til generel web, ASP.NET, C# / VB.NET og ADO.NET. Skrevet den 06. Feb 2009 af arne_v I kategorien Programmering / ASP.NET Historie: V1.0-30/12/2004 - original Hvad er geografisk lokalisering Din side finder ud af hvor brugeren er henne. Typisk hvilket land. Men i nogen tilfælde også hvilken landsdel eller hvilken by. Hvorfor laver man geografisk lokalisering Det kan der være mange grunde til. Nogle eksempler: 1) Man vil forbyde adgang til hele siten eller visse sider fra enkelte lande eller eventuelt alle andre lande end ens eget p.g.a. lovmæssige krav. 2) Man vil automatisk skifte til sider i brugerens sprog. 3) Man vil generere sider som viser nærmeste butikker eller nærmeste download server eller lignende. Hvordan laver man geografisk lokalisering Man henter adressen på client maskinen fra HTTP headeren Remote-Addr og slår op i en database som mapper fra IP adresser til geografisk lokation. Kan det ikke gøres nemmere? Man kigger på HTTP headeren Accept-Language og ser hvilket sprog browseren er sat til. I praksis er det ubrugeligt, da masser af ikke personer i ikke engelsk talende lande bruger engelske versioner

af software. Man laver reverse DNS lookup på adressen på client maskinen og ser hvilket land domæne navnet tilhører. I praksis er det ubrugeligt, da meget almindelige domæner som.com.org.net.biz etc. ikke nødvendigvis er USA. Man beder brugeren selv vælge sprog eller nærmeste butik / download site. Det virker naturligvis for disse formål. Og er absolut en simpel og nem løsning, som man bør overveje. Løsningen kan åbenlyst ikke bruges til at blokere for uønskede med. Geo lokaliserings databaser Man skal som sagt have en database der mapper fra IP adresser til land. Der eksisterer adskillige sådanne. En masse kommercielle og enkelte gratis. Det er vigtigt at huske at den database skal løbende opdateres, da internettet ikke er statisk. Man skal også gøre sig klart at det ikke er en 100% sikker lokalisering. Forskellene på de kommercielle og de gratis er typisk: * de gratis er kun på land - de kommercielle er både land og landsdel/by * de gratis har 90-95% sikkerhed - de kommercielle har 95-98% sikkerhed * de gratis opdateres en gang om måneden - de kommercielle opdateres hver dag Jeg kender 2 gratis: * http://ip-to-country.webhosting.info/ * http://www.maxmind.com/app/geoip_country Inden du starter brug af dem, så skal du nærlæse deres licens betingelser og checke om de er kompatible med dit brug. Nedenstående kode viser hvordan de kan bruges. Du vælger hvilken af de 2 du vil bruge og retter eventuelt koden til så den passer til dit formål. Database byg kode GeoLoad.cs using System; using System.IO; using System.Net; using System.Data; using System.Data.SqlClient; using ICSharpCode.SharpZipLib.Zip;

namespace E_Geo public class GeoLoad /* START CONFIGURATION */ private const String UrlWebHostingInfo = "http://ip-to-country.webhosting.info/downloads/ip-to-country.csv.zip"; private const String UrlMaxMind = "http://www.maxmind.com/download/geoip/database/geoipcountrycsv.zip"; private const String WorkDir = @"C:\e"; private const String ConnStr = "server=arnepc2;integrated Security=SSPI;database=Test"; /* END CONFIGURATION */ private static void Download(string urlstr, string zipfnm) WebClient wc = new WebClient(); wc.downloadfile(urlstr, WorkDir + @"\" + zipfnm); private static void Unzip(string zipfnm, string csvfnm) Stream s = new FileStream(WorkDir + @"\" + csvfnm, FileMode.Create, FileAccess.Write); ZipInputStream zis = new ZipInputStream(new FileStream(WorkDir + @"\" + zipfnm, FileMode.Open, FileAccess.Read)); ZipEntry ze = zis.getnextentry(); byte[] b = new byte[100000]; int n; while((n = zis.read(b, 0, b.length)) > 0) s.write(b, 0, n); zis.close(); s.close(); private static void DbImport(string csvfnm, int fromcol, int tocol, int countrycol, string tblnam) SqlConnection con = new SqlConnection(ConnStr); con.open(); SqlCommand drp = new SqlCommand("DROP TABLE " + tblnam, con); try drp.executenonquery(); catch(exception) /* we will end here first time */ SqlCommand cre1 = new SqlCommand("CREATE TABLE " + tblnam + "(id INTEGER NOT NULL, ip1 NUMERIC(10,0), ip2 NUMERIC(10,0), country CHAR(2), PRIMARY KEY(id))", con); cre1.executenonquery(); SqlCommand cre2 = new SqlCommand("CREATE INDEX ixip1 ON " + tblnam + "(ip1)", con); cre2.executenonquery();

SqlCommand cre3 = new SqlCommand("CREATE INDEX ixip2 ON " + tblnam + "(ip2)", con); cre3.executenonquery(); SqlCommand ins = new SqlCommand("INSERT INTO " + tblnam + " VALUES(@id,@ip1,@ip2,@country)", con); ins.parameters.add("@id", SqlDbType.Int); ins.parameters.add("@ip1", SqlDbType.Decimal); ins.parameters.add("@ip2", SqlDbType.Decimal); ins.parameters.add("@country", SqlDbType.VarChar); StreamReader sr = new StreamReader(WorkDir + @"\" + csvfnm); int n = 0; string line; while((line = sr.readline())!= null) n++; string[] cols = line.split(",".tochararray()); decimal fromval = decimal.parse(cols[fromcol-1].replace('"', ' ').Trim()); decimal toval = decimal.parse(cols[tocol-1].replace('"', ' ').Trim()); string code = cols[countrycol-1].replace('"', ' ').Trim(); ins.parameters["@id"].value = n; ins.parameters["@ip1"].value = fromval; ins.parameters["@ip2"].value = toval; ins.parameters["@country"].value = code; ins.executenonquery(); sr.close(); con.close(); private static void LoadWebHostingInfo() Download(UrlWebHostingInfo, "whi.zip"); Unzip("whi.zip", "whi.csv"); DbImport("whi.csv", 1, 2, 3, "whi"); private static void LoadMaxMind() Download(UrlMaxMind, "mm.zip"); Unzip("mm.zip", "mm.csv"); DbImport("mm.csv", 3, 4, 5, "mm"); public static void Main(string[] args) LoadWebHostingInfo(); LoadMaxMind(); GeoLoad.vb

Imports System Imports System.IO Imports System.Net Imports System.Data Imports System.Data.SqlClient Imports ICSharpCode.SharpZipLib.Zip Namespace E_Geo Public Class GeoLoad Private Const UrlWebHostingInfo As String = "http://ip-to-country.webhosting.info/downloads/ip-to-country.csv.zip" Private Const UrlMaxMind As String = "http://www.maxmind.com/download/geoip/database/geoipcountrycsv.zip" Private Const WorkDir As String = "C:\e" Private Const ConnStr As String = "server=arnepc2;integrated Security=SSPI;database=Test" String) Private Shared Sub Download(ByVal urlstr As String, ByVal zipfnm As Dim wc As WebClient = New WebClient wc.downloadfile(urlstr, WorkDir + "\" + zipfnm) Private Shared Sub Unzip(ByVal zipfnm As String, ByVal csvfnm As String) Dim s As Stream = New FileStream(WorkDir + "\" + csvfnm, FileMode.Create, FileAccess.Write) Dim zis As ZipInputStream = New ZipInputStream(New FileStream(WorkDir + "\" + zipfnm, FileMode.Open, FileAccess.Read)) Dim ze As ZipEntry = zis.getnextentry Dim b(100000) As Byte Dim n As Integer n = zis.read(b, 0, b.length) While n > 0 s.write(b, 0, n) n = zis.read(b, 0, b.length) End While zis.close s.close Private Shared Sub DbImport(ByVal csvfnm As String, ByVal fromcol As Integer, ByVal tocol As Integer, ByVal countrycol As Integer, ByVal tblnam As String) Dim con As SqlConnection = New SqlConnection(ConnStr) con.open Dim drp As SqlCommand = New SqlCommand("DROP TABLE " + tblnam, con) Try drp.executenonquery Catch e As Exception ' we will end here first time End Try Dim cre1 As SqlCommand = New SqlCommand("CREATE TABLE " + tblnam + "(id INTEGER NOT NULL, ip1 NUMERIC(10,0), ip2 NUMERIC(10,0), country CHAR(2),

PRIMARY KEY(id))", con) cre1.executenonquery Dim cre2 As SqlCommand = New SqlCommand("CREATE INDEX ixip1 ON " + tblnam + "(ip1)", con) cre2.executenonquery Dim cre3 As SqlCommand = New SqlCommand("CREATE INDEX ixip2 ON " + tblnam + "(ip2)", con) cre3.executenonquery Dim ins As SqlCommand = New SqlCommand("INSERT INTO " + tblnam + " VALUES(@id,@ip1,@ip2,@country)", con) ins.parameters.add("@id", SqlDbType.Int) ins.parameters.add("@ip1", SqlDbType.Decimal) ins.parameters.add("@ip2", SqlDbType.Decimal) ins.parameters.add("@country", SqlDbType.VarChar) Dim sr As StreamReader = New StreamReader(WorkDir + "\" + csvfnm) Dim n As Integer = 0 Dim line As String line = sr.readline While Not (line Is Nothing) n = n + 1 Dim cols As String() = line.split(",".tochararray) Dim fromval As Decimal = Decimal.Parse(cols(fromcol - 1).Replace("""", " ").Trim) Dim toval As Decimal = Decimal.Parse(cols(tocol - 1).Replace("""", " ").Trim) Dim code As String = cols(countrycol - 1).Replace("""", " ").Trim ins.parameters("@id").value = n ins.parameters("@ip1").value = fromval ins.parameters("@ip2").value = toval ins.parameters("@country").value = code ins.executenonquery line = sr.readline End While sr.close con.close Private Shared Sub LoadWebHostingInfo() 'Download(UrlWebHostingInfo, "whi.zip") Unzip("whi.zip", "whi.csv") DbImport("whi.csv", 1, 2, 3, "whi") Private Shared Sub LoadMaxMind() 'Download(UrlMaxMind, "mm.zip") Unzip("mm.zip", "mm.csv") DbImport("mm.csv", 3, 4, 5, "mm") Public Shared Sub Main(ByVal args As String()) LoadWebHostingInfo LoadMaxMind End Class

End Namespace Bemærk at dette program gør det hele: - downloader zip fil - udpakker csv fil fra zip fil - loader csv fil til databasen Du skal kun tilrette konfigurationen i toppen. Koden bruger SharpZipLib som kan hentes her: http://www.icsharpcode.net/opensource/sharpziplib/default.aspx Database søge kode GeoLocate.cs using System; using System.Collections; using System.Net; using System.Data.SqlClient; namespace E_Geo public class GeoLocate /* START CONFIGURATION */ private const String ConnStr = "server=arnepc2;integrated Security=SSPI;database=Test"; /* END CONFIGURATION */ private static SqlConnection con; private static Hashtable cache; static GeoLocate() string connstrcopy = ConnStr; con = new SqlConnection(connstrcopy); con.open(); cache = new Hashtable(); public static string Locate(string ip, string tblnam) string country = (string)cache[ip]; if(country == null) byte[] b = Dns.Resolve(ip).AddressList[0].GetAddressBytes(); long ipnum = 0; for(int i = 0; i < 4; i++) ipnum = (ipnum << 8) (uint)(b[i] & 0xFF); lock(con) SqlCommand sel = new SqlCommand("SELECT country FROM " + tblnam + " WHERE ip1 < " + ipnum + " AND " + ipnum + " < ip2", con); SqlDataReader rdr = sel.executereader();

if(rdr.read()) country = (string)rdr[0]; else country = "??"; rdr.close(); cache.add(ip, country); return country; GeoLocate.vb Imports System Imports System.Collections Imports System.Net Imports System.Data.SqlClient Namespace E_Geo Public Class GeoLocate Private Const ConnStr As String = "server=arnepc2;integrated Security=SSPI;database=Test" Private Shared con As SqlConnection Private Shared cache As Hashtable Shared Sub New() Dim connstrcopy As String = ConnStr con = New SqlConnection(connstrcopy) con.open cache = New Hashtable Public Shared Function Locate(ByVal ip As String, ByVal tblnam As String) As String Dim country As String = CType(cache(ip), String) If country Is Nothing Then Dim b As Byte() = Dns.Resolve(ip).AddressList(0).GetAddressBytes Dim ipnum As Long = 0 Dim i As Integer For i = 0 To 3 ipnum = (ipnum << 8) Or (b(i) And &HFF) Next SyncLock con Dim sel As SqlCommand = New SqlCommand("SELECT country FROM " + tblnam + " WHERE ip1 < " + ipnum.tostring + " AND " + ipnum.tostring

+ " < ip2", con) Dim rdr As SqlDataReader = sel.executereader If rdr.read Then country = CType(rdr(0), String) Else country = "??" End If rdr.close cache.add(ip, country) End SyncLock End If Return country End Function End Class End Namespace test.aspx <%@ Page Language="C#" %> <%@ import namespace="e_geo" %> <%=GeoLocate.Locate(Request.UserHostAddress, "whi")%> <%=GeoLocate.Locate(Request.UserHostAddress, "mm")%> test.aspx <%@ Page Language="VB" %> <%@ import namespace="e_geo" %> <%=GeoLocate.Locate(Request.UserHostAddress, "whi")%> <%=GeoLocate.Locate(Request.UserHostAddress, "mm")%> Du skal selvfølgelig også tilrette konfigurationen her..dlll filen og.aspx filen der bruger den skal deployes helt normalt (ligger udenfor scope af denne artikel). De viste test.aspx er naturligvis uinteressante, men de viser hvordan man kalder. Kommentar af wever d. 02. Dec 2008 1 Fin artikel, arne_v rundede 800.000 point da jeg købte adgang :) Kommentar af tofte d. 31. Dec 2004 2 Belyser problemer, og kommer med en fin løsning. Kommentar af olhansen d. 22. Feb 2007 3

Fin løsning Kommentar af rasmus-madsen d. 02. Jan 2005 4 Jeg har nu, efter testning fundet ud af hvor præcis den egentlig var... Så stemmer lig igen, med bedre karakter ;) Kommentar af madschristensen d. 21. Jun 2005 5 Fin artikel! Kommentar af andr3as d. 31. Dec 2004 6 jeg ved ikke lige hvorfor rasmus-madsen skriver som han gør, men jeg synes det er en meget god artikel!