I am having trouble with the representation of a date in JSON. I am using Service Stack as a web service to get the data from. My code on the server side is as follows:
public object Execute(GetNoPatientList request)
{
NoPatientList _noPatientList = new NoPatientList();
List<string> _noMatchPatientList = new List<string>();
List<NoPatientList> _newList = new List<NoPatientList>();
try
{
using (SqlConnection cn = new SqlConnection(Database.WaldenWebConnection))
{
cn.Open();
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandText = "select [DateTimeStamp] as DateCreated,[ID],[PatientMRN],[FirstName],[MiddleName]"
+ " ,[LastName],convert(varchar,[DOB],101) as DOB,[Sex],[Note],[Source] as Interface"
+ " from PatientNoMatch"
+ " where FoundMatch = 'F'"
+ " and Show = 'T'"
+ " order by DateTimeStamp desc";
SqlDataReader dr = cm.ExecuteReader();
while (dr.Read())
{
NoPatientList _noPatientList1 = new NoPatientList();
_noPatientList1.PatientMRN = dr["PatientMRN"].ToString();
_noPatientList1.FirstName = dr["FirstName"].ToString();
_noPatientList1.MiddleName = dr["MiddleName"].ToString();
_noPatientList1.LastName = dr["LastName"].ToString();
_noPatientList1.DOB = dr["DOB"].ToString();
_noPatientList1.Sex = dr["Sex"].ToString();
_noPatientList1.Note = dr["Note"].ToString();
_noPatientList1.DateCreated = dr.GetDateTime(0);
_noPatientList1.Interface = dr["Interface"].ToString();
_newList.Add(_noPatientList1);
}
return _newList;
}
}
}
catch
{
return _newList;
}
}
The type is represented as follows:
[DataContract]
public class NoPatientList
{
[DataMember]
public string ID { get; set; }
[DataMember]
public string PatientMRN { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string MiddleName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public string Sex { get; set; }
[DataMember]
public string DOB { get; set; }
[DataMember]
public string Note { get; set; }
[DataMember]
public DateTime DateCreated { get; set; }
[DataMember]
public string Interface { get; set; }
}
The web service is being consumed by a Silverlight application from the following call:
/InterfaceUtility/servicestack/json/syncreply/
The Silverlight application is processing the code into a grid using the following code
private void GetNoPatientMatchData()
{
try
{
gridViewNoMatch.ItemsSource = null;
}
catch { }
_client = new WebClient();
_client.OpenReadCompleted += (a, f) =>
{
if (!f.Cancelled && f.Error == null)
{
_listOfNoPatientsMatches = new List<NoPatientList>();
MemoryStream _memoryStream = new MemoryStream();
f.Result.CopyTo(_memoryStream);
_memoryStream.Position = 0;
StreamReader _streamReader = new StreamReader(_memoryStream);
string _memoryStreamToText = _streamReader.ReadToEnd();
List<NoPatientList> _deserializedNoPatientList = (List<NoPatientList>)Newtonsoft.Json.JsonConvert.DeserializeObject(_memoryStreamToText, typeof(List<NoPatientList>));
gridViewNoMatch.ItemsSource = _deserializedNoPatientList;
}
else
{
MessageBox.Show(f.Error.Message,
"Error", MessageBoxButton.OK);
}
};
_client.OpenReadAsync(new Uri(_serviceUri + "getnopatientlist"));
The issue is that the times on DateTime field appear to always 6 hours off.
Any ideas as to what is going on?
This is probably a time zone issue. Check that:
Your webservice is returning you dates/times in UTC format.
Your code is parsing these dates/times as UTC dates and times.
Related
Hi everyone I am new to programming, I am currently trying to create a web service to retrieve the customer information in my database but currently I am unable to solve this error, someone please help me
CustAccounts.svc.cs
public class CustAcc : ICustAccounts
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public List<CustAcc> GetCustAccJSON()
{
List<CustomerAccountDAL> abc = new List<CustomerAccountDAL>();
CustomerAccountDAL caDAL = new CustomerAccountDAL();
List<CustAcc> allAcc = new List<CustAcc>();
allAcc = caDAL.retrieveCustAccount();
//caDAL.retrieveCustAccount();
return allAcc;
}
}
CustomerAccountDAL.cs
public List<CustAcc> retrieveCustAccount()
{
List<CustAcc> acc = new List<CustAcc>();
using (SqlConnection myConnection = new SqlConnection(con))
{
string jString = "Select * from CustDB";
SqlCommand jCmd = new SqlCommand(jString, myConnection);
myConnection.Open();
using (SqlDataReader rr = jCmd.ExecuteReader())
{
while (rr.Read())
{
CustAcc accounts = new CustAcc();
custEmail = rr["custEmail"].ToString();
custPassword = rr["custPassword"].ToString();
acc.Add(accounts);
}
myConnection.Close();
}
}
return acc;
}
CustAcc.cs
public class CustAcc
{
public string custFullName { get; set; }
public string custPreferredName { get; set; }
public string custPassword { get; set; }
public string custEmail { get; set; }
public string custPhoneNumber { get; set; }
public string message { get; set; }
public CustAcc(string custName, string custFullName, string custPreferredName, string custPassword, string custEmail, string custPhoneNumber)
{
this.custFullName = custFullName;
this.custPreferredName = custPreferredName;
this.custPassword = custPassword;
this.custEmail = custEmail;
this.custPhoneNumber = custPhoneNumber;
}
public CustAcc()
{
this.custEmail = custEmail;
this.custPassword = custPassword;
}
}
Move your Model classes to their own assembly called Model and reference the assembly in both the WS and website assemblies.
You will also need to setup the Service reference in your website to look for the Service types in the Model assembly (it's an option in the Add Service Reference wizard).
I have a method that aims to fill a PersonModel from OleDB;
public IEnumerable<PeopleModel> GetPeopleDetails()
{
var constr = ConfigurationManager.ConnectionStrings["dbfString"].ConnectionString;
using (var dbfCon = new OleDbConnection(constr))
{
dbfCon.Open();
using (var dbfCmd = dbfCon.CreateCommand())
{
dbfCmd.CommandText = "SELECT pp_firstname, pp_surname, pp_title, pp_compnm, pp_hmaddr1, pp_hmaddr2, pp_hmtown, pp_hmcounty, pp_hmpcode, pp_spouse, pp_children FROM people ORDERBY pp_surname";
using (var myReader = dbfCmd.ExecuteReader())
{
var peopleList = new List<PeopleModel>();
while (myReader.Read())
{
var details = new PeopleModel
{
details.Firstname = myReader[0].ToString(),
details.Lastname = myReader[1].ToString(),
details.Title = myReader[2].ToString(),
details.Company = myReader[3].ToString(),
details.Addr1 = myReader[4].ToString(),
details.Addr2 = myReader[5].ToString(),
details.Town = myReader[6].ToString(),
details.County = myReader[7].ToString(),
details.Spouse = myReader[8].ToString(),
details.Children = myReader[9].ToString(),
};
peopleList.Add(details);
}
return peopleList;
}
}
}
}
This code is pretty much identical to the method I am using to fill a companies details, which works no problem. Here is the PeopleModel I am using to build a person.
namespace SdcDatabase.Model
{
public class PeopleModel
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Title { get; set; }
public string Company { get; set; }
public string Addr1 { get; set; }
public string Addr2 { get; set; }
public string Town { get; set; }
public string County { get; set; }
public string Spouse { get; set; }
public string Children { get; set; }
}
}
Although the companies method has worked fine previously, I am now getting the following error when I try to build my project after implementing the People code: Cannot initialize type 'PeopleModel' with a collection initializer because it does not implement 'System.Collections.IEnumerable'
I really am at a lost cause with this as it is working in an almost identical method for a Company.
Correct syntax, without details. in the assignments in the initializer:
var details = new PeopleModel
{
Firstname = myReader[0].ToString(),
Lastname = myReader[1].ToString(),
Title = myReader[2].ToString(),
Company = myReader[3].ToString(),
Addr1 = myReader[4].ToString(),
Addr2 = myReader[5].ToString(),
Town = myReader[6].ToString(),
County = myReader[7].ToString(),
Spouse = myReader[8].ToString(),
Children = myReader[9].ToString(),
};
I have the following function which is accessible from one of my asp.net page:
/* QUERY TO RUN FROM ANY FUNCTION */
public void runQuery()
{
strMainSql = #"SELECT
CT.OBJECTID 'Object ID'
FROM HSI.RMOBJECTINSTANCE1224 CT
WHERE CT.ACTIVESTATUS = 0 AND CT.OBJECTID = '" + s + "'";
using (SqlConnection scConn = new SqlConnection(strConn))
{
scConn.Open();
using (SqlCommand scComm = new SqlCommand(strMainSql, scConn))
{
sdrRead = scComm.ExecuteReader();
while (sdrRead.Read())
{
/* CAN BE USED IN OTHER PAGES */
strTaskName = sdrRead[1].ToString();
strTaskDetail = sdrRead[2].ToString();
strTaskStartDate = sdrRead[3].ToString();
strIdentifier = sdrRead[4].ToString();
strStatus = sdrRead[5].ToString();
strDueDate = sdrRead[6].ToString();
strIssueDate = sdrRead[7].ToString();
strCompleted = sdrRead[8].ToString();
strNotes = sdrRead[9].ToString();
strProvider = sdrRead[10].ToString();
strService = sdrRead[11].ToString();
strCheckedDate = sdrRead[12].ToString();
strCheckedStatus = sdrRead[13].ToString();
strCheckedUser = sdrRead[14].ToString();
strClient = sdrRead[15].ToString();
hfMemoID.Value = sdrRead[16].ToString();
hfObjectID.Value = sdrRead[0].ToString();
break;
}
}
}
/* SPECIFIC TO THE PAGE ONLY */
lblUser.Text = strCheckedUser;
lblDateTime.Text = strCheckedDate;
lblTaskName.Text = strTaskName;
lblClient.Text = strClient;
lblID.Text = strIdentifier;
lblSvc.Text = strService;
lblProvider.Text = strProvider;
lblStat.Text = strStatus;
lblDueDate.Text = strDueDate;
lblDetail.Text = strTaskDetail;
lblTaskIssue.Text = strIssueDate;
lblStartDate.Text = strTaskStartDate;
lblCompleted.Text = strCompleted;
}
The question I have is, if I have to use the above function in multiple pages, instead of having a multiple copies of the same function which might lead to issue later on when updating, how do I make it into a class by itself so I can call it from any page and get the value from the SQL query?
What you can do is expose the results from the query as properties and then use the properties in the ASPX page.
using System.Data.SqlClient;
namespace MyNamespace
{
public class Task
{
public string strTaskName { get; set; }
public string strTaskDetail { get; set; }
public string strTaskStartDate { get; set; }
public string strIdentifier { get; set; }
public string strStatus { get; set; }
public string strDueDate { get; set; }
public string strIssueDate { get; set; }
public string strCompleted { get; set; }
public string strNotes { get; set; }
public string strProvider { get; set; }
public string strService { get; set; }
public string strCheckedDate { get; set; }
public string strCheckedStatus { get; set; }
public string strCheckedUser { get; set; }
public string strClient { get; set; }
// you need to define properties for the appropriate datatype on these
//hfMemoID
//hfObjectID
public string strConn { get; set; }
public void Load(string objectid)
{
var strMainSql = #"SELECT
CT.OBJECTID 'Object ID'
FROM HSI.RMOBJECTINSTANCE1224 CT
WHERE CT.ACTIVESTATUS = 0 AND CT.OBJECTID = '" + objectid + "'";
using (SqlConnection scConn = new SqlConnection(strConn))
{
scConn.Open();
using (SqlCommand scComm = new SqlCommand(strMainSql, scConn))
{
var sdrRead = scComm.ExecuteReader();
while (sdrRead.Read())
{
/* CAN BE USED IN OTHER PAGES */
this.strTaskName = sdrRead[1].ToString();
this.strTaskDetail = sdrRead[2].ToString();
this.strTaskStartDate = sdrRead[3].ToString();
this.strIdentifier = sdrRead[4].ToString();
this.strStatus = sdrRead[5].ToString();
this.strDueDate = sdrRead[6].ToString();
this.strIssueDate = sdrRead[7].ToString();
this.strCompleted = sdrRead[8].ToString();
this.strNotes = sdrRead[9].ToString();
this.strProvider = sdrRead[10].ToString();
this.strService = sdrRead[11].ToString();
this.strCheckedDate = sdrRead[12].ToString();
this.strCheckedStatus = sdrRead[13].ToString();
this.strCheckedUser = sdrRead[14].ToString();
this.strClient = sdrRead[15].ToString();
//
//hfMemoID.Value = sdrRead[16].ToString();
//hfObjectID.Value = sdrRead[0].ToString();
break;
}
}
}
}
}
}
In the code behind use the class to load the data and then set the controls using the properties
private MyNamespace.Task Task = new MyNamespace.Task();
protected void Page_Load(object sender, EventArgs e)
{
Task.strConn = "my connection string.";
Task.Load("task id to load");
// set the value into the controls.
lblUser.Text = Task.strCheckedUser;
lblDateTime.Text = Task.strCheckedDate;
lblTaskName.Text = Task.strTaskName;
lblClient.Text = Task.strClient;
lblID.Text = Task.strIdentifier;
lblSvc.Text = Task.strService;
lblProvider.Text = Task.strProvider;
lblStat.Text = Task.strStatus;
lblDueDate.Text = Task.strDueDate;
lblDetail.Text = Task.strTaskDetail;
lblTaskIssue.Text = Task.strIssueDate;
lblStartDate.Text = Task.strTaskStartDate;
lblCompleted.Text = Task.strCompleted;
}
I am trying to extend a class to another class that will collect them as a list.
model:
public class Brand
{
public int BrandId { get; set; }
public string Name { get; set; }
public string Guid { get; set; }
public float Rating { get; set; }
public string Industry { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postal { get; set; }
public string CountryCode { get; set; }
public virtual Snapshot Snapshot { get; set; }
}
public class Snapshot
{
public int ID { get; set; }
public string Guid { get; set; }
public int CompanyID { get; set; }
public string CompanyName { get; set; }
public string Email { get; set; }
public DateTime DateTimeSent { get; set; }
public string Subject { get; set; }
public string Html { get; set; }
public string Image { get; set; }
public string Unsubscribe { get; set; }
}
public class BrandSnaphotViewModel
{
public Brand Brand { get; set; }
public List<Snapshot> SnapshotItems { get; set; }
}
controller:
public ActionResult Index(string brandGuid)
{
BrandSnaphotViewModel viewModel = new BrandSnaphotViewModel();
Brand brand = GetBrand(brandGuid);
viewModel.Brand = brand;
List<Snapshot> snapshot = GetBrandSnapshots(brand.BrandId);
viewModel.SnapshotItems = snapshot;
List<BrandSnaphotViewModel> viewModelList = new List<BrandSnaphotViewModel>();
viewModelList.Add(viewModel);
return View(viewModelList.AsEnumerable());
}
private Brand GetBrand(string brandGuid)
{
Brand brand = new Brand();
string dbConnString = WebConfigurationManager.ConnectionStrings["dbConn"].ConnectionString;
MySqlConnection dbConn = new MySqlConnection(dbConnString);
dbConn.Open();
MySqlCommand dbCmd = new MySqlCommand();
dbCmd.CommandText = "SELECT *, industries.name AS industry_name FROM brands LEFT JOIN industries ON brands.industry_id = industries.industry_id WHERE brand_guid = '" + brandGuid.ToString() + "' AND private = 0 LIMIT 1";
dbCmd.Connection = dbConn;
MySqlDataReader dbResult = dbCmd.ExecuteReader();
if (dbResult.Read())
{
brand.Guid = dbResult["brand_guid"].ToString();
brand.BrandId = Convert.ToInt32(dbResult["brand_id"]);
brand.Industry = dbResult["industry_name"].ToString();
}
dbResult.Close();
dbConn.Close();
return brand;
}
private List<Snapshot> GetBrandSnapshots(int brandId)
{
string dbConnString = WebConfigurationManager.ConnectionStrings["dbConn"].ConnectionString;
MySqlConnection dbConn = new MySqlConnection(dbConnString);
dbConn.Open();
MySqlCommand dbCmd = new MySqlCommand();
dbCmd.CommandText = "SELECT * FROM snapshots WHERE brand_id = " + brandId + " AND archive = 0 ORDER BY date_sent DESC";
dbCmd.Connection = dbConn;
MySqlDataReader dbResult = dbCmd.ExecuteReader();
List<Snapshot> snapshots = new List<Snapshot>();
while (dbResult.Read())
{
snapshots.Add(new Snapshot
{
SnapshotId = Convert.ToInt32(dbResult["snapshot_id"]),
Subject = dbResult["subject"].ToString(),
DateTimeSent = Convert.ToDateTime(dbResult["date_sent"]),
Image = dbResult["image"].ToString(),
Email = dbResult["email"].ToString(),
ContentType = dbResult["content_type"].ToString(),
Type = dbResult["type"].ToString()
});
}
dbResult.Close();
dbConn.Close();
return snapshots;
}
edit
FIXED
The issue was the VIEW was not referencing the ViewModel as an IENumerable<>. FACEPALM.
#model IEnumerable<projectvia.ViewModels.BrandSnaphotViewModel>
#{
ViewBag.Title = "Index";
}
#foreach(var item in Model)
{
#item.Brand.Guid;
for(int i = 0; i< #item.SnapshotItems.Count; i++)
{
#item.SnapshotItems[i].Subject<br/>
}
}
That resolved the issue.
Thank you both experts for the insights... i took both advice and came to this solution.
you are doing wrong, it is a list.
you cannot add element this way. Create object and add that object in list by calling Add()
do like this to add items in it:
List<BrandEmailList> brandSnapshotsList = new List<BrandEmailList>();
while (dbResult.Read())
{
BrandEmailList brandSnapshots = new BrandEmailList (); // create an object
brandSnapshots.ID = Convert.ToInt32(dbResult["snapshot_id"]);
brandSnapshots.Guid = dbResult["snapshot_guid"].ToString();
brandSnapshots.DateTimeSent = dbResult["date_sent"];
brandSnapshots.Subject = dbResult["subject"].ToString();
brandSnapshots.Image = dbResult["image"];
brandSnapshotsList.Add(brandSnapshots); // add it in list
}
EDIT:
List is a generic thing, you don't need to create a class for it. you can just instantiate a list and add items in it.
why are you doing like that you can do it this way simply:
List<Snapshot> brandSnapshotsList = new List<Snapshot>();
while (dbResult.Read())
{
Snapshot brandSnapshots = new Snapshot(); // create an object
brandSnapshots.ID = Convert.ToInt32(dbResult["snapshot_id"]);
brandSnapshots.Guid = dbResult["snapshot_guid"].ToString();
brandSnapshots.DateTimeSent = dbResult["date_sent"];
brandSnapshots.Subject = dbResult["subject"].ToString();
brandSnapshots.Image = dbResult["image"];
brandSnapshotsList.Add(brandSnapshots); // add it in list
}
Building on what Ehsan Sajjad did, looking at public IEnumerator<Snapshot> BrandEmails, i believe what you look for looks more like this:
public class Snapshot
{
public int ID { get; set; }
public string Guid { get; set; }
// ...
}
public class BrandEmailList : List<Snapshot>
{
}
You need not even create a new type for your brand email list, you can use List<Snapshot> directly.
public ViewResult Whatever() {
var brand = GetBrand(brandName);
var brandSnapshots = GetBrandSnapshots();
return View(brand, brandSnapshots);
}
private Brand GetBrand(string brandName)
{
try
{
var brand = new Brand();
brand.Name = brandName;
// database stuffs ...
return brand;
}
catch (Exception ex)
{
throw ex;
}
}
private List<Snapshot> GetBrandSnapshots()
{
// ...
// DB stuffs -- that *really* should not be in the controller anyways.
// ...
var snapshots = new List<BrandEmailList>();
while (dbResult.Read())
{
// object initializer syntax
snapshots.Add(new Snapshot {
ID = Convert.ToInt32(dbResult["snapshot_id"]),
Guid = dbResult["snapshot_guid"].ToString(),
DateTimeSent = dbResult["date_sent"],
Subject = dbResult["subject"].ToString(),
Image = dbResult["image"],
});
}
return snapshots
}
As a side note, mixing database access into controller methods can be a bad idea. It does not have to be, but it can be. Generally, fetching data from the database happens at a different "level" than serving a MVC result. MVC controller don't have the "purpose" to talk to a database, that work can/should be delegated to a dedicated type. Compare the single responsibility principle part of the SOLID principles.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 months ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I have an ASP.NET website written in C#.
On this site I need to automatically show a start page based on the user's location.
Can I get name of user's city based on the IP address of the user ?
You need an IP-address-based reverse geocoding API... like the one from ipdata.co. I'm sure there are plenty of options available.
You may want to allow the user to override this, however. For example, they could be on a corporate VPN which makes the IP address look like it's in a different country.
Use http://ipinfo.io , You need to pay them if you make more than 1000 requests per day.
The code below requires the Json.NET package.
public static string GetUserCountryByIp(string ip)
{
IpInfo ipInfo = new IpInfo();
try
{
string info = new WebClient().DownloadString("http://ipinfo.io/" + ip);
ipInfo = JsonConvert.DeserializeObject<IpInfo>(info);
RegionInfo myRI1 = new RegionInfo(ipInfo.Country);
ipInfo.Country = myRI1.EnglishName;
}
catch (Exception)
{
ipInfo.Country = null;
}
return ipInfo.Country;
}
And the IpInfo Class I used:
public class IpInfo
{
[JsonProperty("ip")]
public string Ip { get; set; }
[JsonProperty("hostname")]
public string Hostname { get; set; }
[JsonProperty("city")]
public string City { get; set; }
[JsonProperty("region")]
public string Region { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("loc")]
public string Loc { get; set; }
[JsonProperty("org")]
public string Org { get; set; }
[JsonProperty("postal")]
public string Postal { get; set; }
}
Following Code work for me.
Update:
As I am calling a free API request (json base ) IpStack.
public static string CityStateCountByIp(string IP)
{
//var url = "http://freegeoip.net/json/" + IP;
//var url = "http://freegeoip.net/json/" + IP;
string url = "http://api.ipstack.com/" + IP + "?access_key=[KEY]";
var request = System.Net.WebRequest.Create(url);
using (WebResponse wrs = request.GetResponse())
{
using (Stream stream = wrs.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream))
{
string json = reader.ReadToEnd();
var obj = JObject.Parse(json);
string City = (string)obj["city"];
string Country = (string)obj["region_name"];
string CountryCode = (string)obj["country_code"];
return (CountryCode + " - " + Country +"," + City);
}}}
return "";
}
Edit :
First, it was http://freegeoip.net/ now it's https://ipstack.com/ (and maybe now it's a paid service- Free Up to 10,000 request/month)
IPInfoDB has an API that you can call in order to find a location based on an IP address.
For "City Precision", you call it like this (you'll need to register to get a free API key):
http://api.ipinfodb.com/v2/ip_query.php?key=<your_api_key>&ip=74.125.45.100&timezone=false
Here's an example in both VB and C# that shows how to call the API.
I have tried using http://ipinfo.io and this JSON API works perfectly. First, you need to add the below mentioned namespaces:
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Xml;
using System.Collections.Specialized;
For localhost it will give dummy data as AU. You can try hardcoding your IP and get results:
namespace WebApplication4
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string VisitorsIPAddr = string.Empty;
//Users IP Address.
if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
{
//To get the IP address of the machine and not the proxy
VisitorsIPAddr = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
}
else if (HttpContext.Current.Request.UserHostAddress.Length != 0)
{
VisitorsIPAddr = HttpContext.Current.Request.UserHostAddress;`enter code here`
}
string res = "http://ipinfo.io/" + VisitorsIPAddr + "/city";
string ipResponse = IPRequestHelper(res);
}
public string IPRequestHelper(string url)
{
string checkURL = url;
HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
StreamReader responseStream = new StreamReader(objResponse.GetResponseStream());
string responseRead = responseStream.ReadToEnd();
responseRead = responseRead.Replace("\n", String.Empty);
responseStream.Close();
responseStream.Dispose();
return responseRead;
}
}
}
I was able to achieve this in ASP.NET MVC using the client IP address and freegeoip.net API. freegeoip.net is free and does not require any license.
Below is the sample code I used.
String UserIP = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(UserIP))
{
UserIP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
string url = "http://freegeoip.net/json/" + UserIP.ToString();
WebClient client = new WebClient();
string jsonstring = client.DownloadString(url);
dynamic dynObj = JsonConvert.DeserializeObject(jsonstring);
System.Web.HttpContext.Current.Session["UserCountryCode"] = dynObj.country_code;
You can go through this post for more details.Hope it helps!
Using the Request of following web site
http://ip-api.com/
Following is C# code for returning Country and Country Code
public string GetCountryByIP(string ipAddress)
{
string strReturnVal;
string ipResponse = IPRequestHelper("http://ip-api.com/xml/" + ipAddress);
//return ipResponse;
XmlDocument ipInfoXML = new XmlDocument();
ipInfoXML.LoadXml(ipResponse);
XmlNodeList responseXML = ipInfoXML.GetElementsByTagName("query");
NameValueCollection dataXML = new NameValueCollection();
dataXML.Add(responseXML.Item(0).ChildNodes[2].InnerText, responseXML.Item(0).ChildNodes[2].Value);
strReturnVal = responseXML.Item(0).ChildNodes[1].InnerText.ToString(); // Contry
strReturnVal += "(" +
responseXML.Item(0).ChildNodes[2].InnerText.ToString() + ")"; // Contry Code
return strReturnVal;
}
And following is Helper for requesting url.
public string IPRequestHelper(string url) {
HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
StreamReader responseStream = new StreamReader(objResponse.GetResponseStream());
string responseRead = responseStream.ReadToEnd();
responseStream.Close();
responseStream.Dispose();
return responseRead;
}
What you need is called a "geo-IP database". Most of them cost some money (albeit not too expensive), especially fairly precise ones. One of the most widely used is MaxMind's database. They have a fairly good free version of IP-to-city database called GeoLity City - it has lots of restrictions, but if you can cope with that that would be probably your best choice, unless you have some money to spare for a subscription to more accurate product.
And, yeah, they do have a C# API to query geo-IP databases available.
You'll probably have to use an external API, most of which cost money.
I did find this though, seems to be free: http://hostip.info/use.html
Return country
static public string GetCountry()
{
return new WebClient().DownloadString("http://api.hostip.info/country.php");
}
Usage:
Console.WriteLine(GetCountry()); // will return short code for your country
Return info
static public string GetInfo()
{
return new WebClient().DownloadString("http://api.hostip.info/get_json.php");
}
Usage:
Console.WriteLine(GetInfo());
// Example:
// {
// "country_name":"COUNTRY NAME",
// "country_code":"COUNTRY CODE",
// "city":"City",
// "ip":"XX.XXX.XX.XXX"
// }
It's good sample for you:
public class IpProperties
{
public string Status { get; set; }
public string Country { get; set; }
public string CountryCode { get; set; }
public string Region { get; set; }
public string RegionName { get; set; }
public string City { get; set; }
public string Zip { get; set; }
public string Lat { get; set; }
public string Lon { get; set; }
public string TimeZone { get; set; }
public string ISP { get; set; }
public string ORG { get; set; }
public string AS { get; set; }
public string Query { get; set; }
}
public string IPRequestHelper(string url)
{
HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
StreamReader responseStream = new StreamReader(objResponse.GetResponseStream());
string responseRead = responseStream.ReadToEnd();
responseStream.Close();
responseStream.Dispose();
return responseRead;
}
public IpProperties GetCountryByIP(string ipAddress)
{
string ipResponse = IPRequestHelper("http://ip-api.com/xml/" + ipAddress);
using (TextReader sr = new StringReader(ipResponse))
{
using (System.Data.DataSet dataBase = new System.Data.DataSet())
{
IpProperties ipProperties = new IpProperties();
dataBase.ReadXml(sr);
ipProperties.Status = dataBase.Tables[0].Rows[0][0].ToString();
ipProperties.Country = dataBase.Tables[0].Rows[0][1].ToString();
ipProperties.CountryCode = dataBase.Tables[0].Rows[0][2].ToString();
ipProperties.Region = dataBase.Tables[0].Rows[0][3].ToString();
ipProperties.RegionName = dataBase.Tables[0].Rows[0][4].ToString();
ipProperties.City = dataBase.Tables[0].Rows[0][5].ToString();
ipProperties.Zip = dataBase.Tables[0].Rows[0][6].ToString();
ipProperties.Lat = dataBase.Tables[0].Rows[0][7].ToString();
ipProperties.Lon = dataBase.Tables[0].Rows[0][8].ToString();
ipProperties.TimeZone = dataBase.Tables[0].Rows[0][9].ToString();
ipProperties.ISP = dataBase.Tables[0].Rows[0][10].ToString();
ipProperties.ORG = dataBase.Tables[0].Rows[0][11].ToString();
ipProperties.AS = dataBase.Tables[0].Rows[0][12].ToString();
ipProperties.Query = dataBase.Tables[0].Rows[0][13].ToString();
return ipProperties;
}
}
}
And test:
var ipResponse = GetCountryByIP("your ip address or domain name :)");
An Alternative to using an API is to use HTML 5 location Navigator to query the browser about the User location. I was looking for a similar approach as in the subject question but I found that HTML 5 Navigator works better and cheaper for my situation. Please consider that your scinario might be different.
To get the User position using Html5 is very easy:
function getLocation()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(showPosition);
}
else
{
console.log("Geolocation is not supported by this browser.");
}
}
function showPosition(position)
{
console.log("Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude);
}
Try it yourself on W3Schools Geolocation Tutorial
public static string GetLocationIPAPI(string ipaddress)
{
try
{
IPDataIPAPI ipInfo = new IPDataIPAPI();
string strResponse = new WebClient().DownloadString("http://ip-api.com/json/" + ipaddress);
if (strResponse == null || strResponse == "") return "";
ipInfo = JsonConvert.DeserializeObject<IPDataIPAPI>(strResponse);
if (ipInfo == null || ipInfo.status.ToLower().Trim() == "fail") return "";
else return ipInfo.city + "; " + ipInfo.regionName + "; " + ipInfo.country + "; " + ipInfo.countryCode;
}
catch (Exception)
{
return "";
}
}
public class IPDataIPINFO
{
public string ip { get; set; }
public string city { get; set; }
public string region { get; set; }
public string country { get; set; }
public string loc { get; set; }
public string postal { get; set; }
public int org { get; set; }
}
==========================
public static string GetLocationIPINFO(string ipaddress)
{
try
{
IPDataIPINFO ipInfo = new IPDataIPINFO();
string strResponse = new WebClient().DownloadString("http://ipinfo.io/" + ipaddress);
if (strResponse == null || strResponse == "") return "";
ipInfo = JsonConvert.DeserializeObject<IPDataIPINFO>(strResponse);
if (ipInfo == null || ipInfo.ip == null || ipInfo.ip == "") return "";
else return ipInfo.city + "; " + ipInfo.region + "; " + ipInfo.country + "; " + ipInfo.postal;
}
catch (Exception)
{
return "";
}
}
public class IPDataIPAPI
{
public string status { get; set; }
public string country { get; set; }
public string countryCode { get; set; }
public string region { get; set; }
public string regionName { get; set; }
public string city { get; set; }
public string zip { get; set; }
public string lat { get; set; }
public string lon { get; set; }
public string timezone { get; set; }
public string isp { get; set; }
public string org { get; set; }
public string #as { get; set; }
public string query { get; set; }
}
==============================
private static string GetLocationIPSTACK(string ipaddress)
{
try
{
IPDataIPSTACK ipInfo = new IPDataIPSTACK();
string strResponse = new WebClient().DownloadString("http://api.ipstack.com/" + ipaddress + "?access_key=XX384X1XX028XX1X66XXX4X04XXXX98X");
if (strResponse == null || strResponse == "") return "";
ipInfo = JsonConvert.DeserializeObject<IPDataIPSTACK>(strResponse);
if (ipInfo == null || ipInfo.ip == null || ipInfo.ip == "") return "";
else return ipInfo.city + "; " + ipInfo.region_name + "; " + ipInfo.country_name + "; " + ipInfo.zip;
}
catch (Exception)
{
return "";
}
}
public class IPDataIPSTACK
{
public string ip { get; set; }
public int city { get; set; }
public string region_code { get; set; }
public string region_name { get; set; }
public string country_code { get; set; }
public string country_name { get; set; }
public string zip { get; set; }
}