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; }
}
Related
I am calling the API for creating a meeting on a fixed date & time. I am using Microsoft Graph API for this. Here is the URL
var url = "https://graph.microsoft.com/v1.0/me/events";
I have taken care of the Authentication part and my code does the following thing to send the JSON response to the API
private async void sendInvites_Click(object sender, RoutedEventArgs e)
{
var httpClient = new System.Net.Http.HttpClient();
System.Net.Http.HttpResponseMessage response;
var url = "https://graph.microsoft.com/v1.0/me/events";
CIBC.Models.SendMeetingInvites.RootObject obj = new CIBC.Models.SendMeetingInvites.RootObject();
CIBC.Models.SendMeetingInvites.Location loc = new CIBC.Models.SendMeetingInvites.Location();
loc.displayName = GlobalVariables.MeetingRoomName;
//loc.RoomEmailAddress = GlobalVariables.meetingRoomEmailID.ToString();
obj.subject = "Maths";
CIBC.Models.SendMeetingInvites.Body body = new CIBC.Models.SendMeetingInvites.Body();
body.content = "Its a booking for follow up meeting";
body.contentType = "HTML";
obj.body = body;
List<CIBC.Models.SendMeetingInvites.Attendee> attens = new List<Models.SendMeetingInvites.Attendee>();
for(int i=0;i<GlobalVariables.NumberOfParticipant.Count;i++)
{
CIBC.Models.SendMeetingInvites.EmailAddress email = new CIBC.Models.SendMeetingInvites.EmailAddress();
CIBC.Models.SendMeetingInvites.Attendee atten = new CIBC.Models.SendMeetingInvites.Attendee();
email.address = GlobalVariables.NumberOfParticipant[i].ParticipantADdress;
atten.emailAddress = email;
atten.type = "Required";
attens.Add(atten);
}
CIBC.Models.SendMeetingInvites.Start start = new CIBC.Models.SendMeetingInvites.Start();
start.dateTime = GlobalVariables.sendMeetingInviteStartDate;
start.timeZone = "UTC";
obj.start = start;
CIBC.Models.SendMeetingInvites.End end = new CIBC.Models.SendMeetingInvites.End();
end.dateTime = GlobalVariables.sendMeetingInviteEndTime;
end.timeZone = "UTC";
obj.end = end;
obj.attendees = attens;
obj.location = loc;
string postBody = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
// var postBody1 = "{'Subject':'Testing Organizer - 12','Location':{'DisplayName':'Some place'}," +
//"'Start': {'DateTime': '2016-07-15T15:00:00.0000000', 'TimeZone':'UTC'}," +
//"'End': {'DateTime': '2016-07-15T15:30:00.0000000', 'TimeZone':'UTC'}," +
//"'Body':{'Content': 'This is a test of Grap API.', 'ContentType':'Text'}," +
//"'IsOrganizer':'False','Organizer':{'EmailAddress': " + "{'Address':'organizer#some.com'} }}";
// var requestString = #"{"subject":"My event","start":{"dateTime":"2017-09-25T07:44:27.448Z","timeZone":"UTC"},"end":{"dateTime":"2017-10-02T07:44:27.448Z","timeZone":"UTC"}}"";
var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, url);
//Add the token in Authorization header
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer",GlobalVariables.Token);
request.Content = new StringContent(postBody, UTF8Encoding.UTF8, "application/json");
response = await httpClient.SendAsync(request);
if (response.IsSuccessStatusCode)
{ }
// return await response.Content.ReadAsStringAsync();
else
{
}
//return "";
}
Here is the class file that I am using to pass to the HTTPResponse Message
namespace CIBC.Models.SendMeetingInvites
{
public class Body
{
public string contentType { get; set; }
public string content { get; set; }
}
public class Start
{
public DateTime dateTime { get; set; }
public string timeZone { get; set; }
}
public class End
{
public DateTime dateTime { get; set; }
public string timeZone { get; set; }
}
public class Location
{
public string displayName { get; set; }
//public string RoomEmailAddress { get; set; }
}
public class EmailAddress
{
public string address { get; set; }
public string name { get; set; }
}
public class Attendee
{
public EmailAddress emailAddress { get; set; }
public string type { get; set; }
}
public class RootObject
{
public string subject { get; set; }
public Body body { get; set; }
public Start start { get; set; }
public End end { get; set; }
public Location location { get; set; }
public List<Attendee> attendees { get; set; }
}
}
My requirement is to send a meeting invite to all the users and also mentioning the Room Details like Name& Email ID of the room.
I tried adding a RoomEmail address in the Request as under The Location class
public string RoomEmailAddress { get; set; }
When I tested this using Microsoft Graph Explorer website , i got the error message
{
"error": {
"code": "RequestBodyRead",
"message": "The property 'RoomEmailAddress' does not exist on type 'Microsoft.OutlookServices.Location'. Make sure to only use
property names that are defined by the type or mark the type as open
type.",
"innerError": {
"request-id": "1883d87d-a5d6-4357-a699-7c112da0e56b",
"date": "2017-09-26T12:03:50"
}
} }
How do I make sure that whenever I create a meeting request , I can assign a room to it?
Currently I am just able to pass DisplayName while sending the Request to the URL.
Once I remove the Email Address property (I added myself ), the code returns Success.
Any workarounds so that I can send the room email address also so that the room also receives a copy of the meeting invite ?
Add the room as an attendee with "type": "Resource". Then add the room's display name in the location property.
I want to get all variables from https://api.coinmarketcap.com/v1/ticker/ in my c# console application.
How can I do this?
I started with getting the whole page as a stream. What to do now?
private static void start_get()
{
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create
(string.Format("https://api.coinmarketcap.com/v1/ticker/"));
WebReq.Method = "GET";
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
Console.WriteLine(WebResp.StatusCode);
Console.WriteLine(WebResp.Server);
Stream Answer = WebResp.GetResponseStream();
StreamReader _Answer = new StreamReader(Answer);
Console.WriteLine(_Answer.ReadToEnd());
}
First you need a custom class to use for deserialization:
public class Item
{
public string id { get; set; }
public string name { get; set; }
public string symbol { get; set; }
public string rank { get; set; }
public string price_usd { get; set; }
[JsonProperty(PropertyName = "24h_volume_usd")] //since in c# variable names cannot begin with a number, you will need to use an alternate name to deserialize
public string volume_usd_24h { get; set; }
public string market_cap_usd { get; set; }
public string available_supply { get; set; }
public string total_supply { get; set; }
public string percent_change_1h { get; set; }
public string percent_change_24h { get; set; }
public string percent_change_7d { get; set; }
public string last_updated { get; set; }
}
Next, you can use Newtonsoft Json, a free JSON serialization and deserialization framework in the following way to get your items (include the following using statements):
using System.Net;
using System.IO;
using Newtonsoft.Json;
private static void start_get()
{
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(string.Format("https://api.coinmarketcap.com/v1/ticker/"));
WebReq.Method = "GET";
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
Console.WriteLine(WebResp.StatusCode);
Console.WriteLine(WebResp.Server);
string jsonString;
using (Stream stream = WebResp.GetResponseStream()) //modified from your code since the using statement disposes the stream automatically when done
{
StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8);
jsonString = reader.ReadToEnd();
}
List<Item> items = JsonConvert.DeserializeObject<List<Item>>(jsonString);
Console.WriteLine(items.Count); //returns 921, the number of items on that page
}
Finally, the list of elements is stored in items.
A simplified version of Keyur PATEL's work.
static void GetCoinValues()
{
string json = new WebClient().DownloadString("https://api.coinmarketcap.com/v1/ticker/");
List<Item> items = JsonConvert.DeserializeObject<List<Item>>(json);
foreach (var item in items)
{
Console.WriteLine("ID: " + item.id.ToUpper());
Console.WriteLine("Name: " + item.name.ToUpper());
Console.WriteLine("Symbol: " + item.symbol.ToUpper());
Console.WriteLine("Rank: " + item.rank.ToUpper());
Console.WriteLine("Price (USD): " + item.price_usd.ToUpper());
Console.WriteLine("\n");
}
}
i am using daily motion API for uploading videos from my application but when try to upload more than 2 MB sized video i get this error "The request was aborted: The request was canceled." and this error invoked by this line of code var responseBytes = client.UploadFile(uploadUrl, fileToUpload);
and this is my code which i am using to upload video
public static void Main(MyVideo video)
{
var accessToken = GetAccessToken();
Authorize(accessToken);
var fileToUpload = video.Path;
var uploadUrl = GetFileUploadUrl(accessToken);
var response = GetFileUploadResponse(fileToUpload, accessToken, uploadUrl);
var uploadedResponse = PublishVideo(response, accessToken);
}
public class UploadResponse
{
public string format { get; set; }
public string acodec { get; set; }
public string vcodec { get; set; }
public int duration { get; set; }
public int bitrate { get; set; }
public string dimension { get; set; }
public string name { get; set; }
public int size { get; set; }
public string url { get; set; }
public string hash { get; set; }
public string seal { get; set; }
public override string ToString()
{
var flags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy;
System.Reflection.PropertyInfo[] infos = this.GetType().GetProperties(flags);
StringBuilder sb = new StringBuilder();
string typeName = this.GetType().Name;
sb.AppendLine(typeName);
sb.AppendLine(string.Empty.PadRight(typeName.Length + 5, '='));
foreach (var info in infos)
{
object value = info.GetValue(this, null);
sb.AppendFormat("{0}: {1}{2}", info.Name, value != null ? value : "null", Environment.NewLine);
}
return sb.ToString();
}
}
private static UploadResponse GetFileUploadResponse(string fileToUpload, string accessToken, string uploadUrl)
{
// ServicePointManager.DefaultConnectionLimit = 900000;
//HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(uploadUrl);
//wr.KeepAlive = false;
//wr.Timeout = System.Threading.Timeout.Infinite;
//wr.ProtocolVersion = HttpVersion.Version10;
var client = new WebClient();
client.Headers.Add("Authorization", "OAuth " + accessToken);
var responseBytes = client.UploadFile(uploadUrl, fileToUpload);
var responseString = Encoding.UTF8.GetString(responseBytes);
var response = JsonConvert.DeserializeObject<UploadResponse>(responseString);
return response;
}
and i have already tried al the possible solutionsu provided on Stackoverflow earlier also done with http execution time and we client time out but not working please someone help me
I'm using the official version 2 of the Constant Contact .net-sdk found here.
I've been unable to find methods for the following:
Creating a Contact List
Adding a contact to a Contact List
Removing a contact from a Contact List
Adding multiple contacts to a Contact List
Creating an Email Campaign
These features clearly exist in v2 of the API found here, but seem missing from the SDK.
Any help in accessing this functionality is appreciated.
Create Contact.
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<Replace with your oAuth Token>");
ContactObject cont = new ContactObject
{
first_name = "Deepu",
last_name = "Madhusoodanan"
};
var email_addresses = new List<EmailAddress>
{
new EmailAddress{email_address = "deepumi1#gmail.com"}
};
cont.email_addresses = email_addresses;
cont.lists = new List<List>
{
new List {id = "<Replace with your List Id>"}
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(cont);
string MessageType = "application/json";
using (var request = new HttpRequestMessage(System.Net.Http.HttpMethod.Post, "https://api.constantcontact.com/v2/contacts?api_key=<Replace with your API key>"))
{
request.Headers.Add("Accept", MessageType);
request.Content = new StringContent(json);
request.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(MessageType);
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
string responseXml = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var code = response.StatusCode;
}
request.Content.Dispose();
}
}
}
catch (Exception exp)
{
//log exception here
}
/*Model class*/
public class Address
{
public string address_type { get; set; }
public string city { get; set; }
public string country_code { get; set; }
public string line1 { get; set; }
public string line2 { get; set; }
public string line3 { get; set; }
public string postal_code { get; set; }
public string state_code { get; set; }
public string sub_postal_code { get; set; }
}
public class List
{
public string id { get; set; }
}
public class EmailAddress
{
public string email_address { get; set; }
}
public class ContactObject
{
public List<Address> addresses { get; set; }
public List<List> lists { get; set; }
public string cell_phone { get; set; }
public string company_name { get; set; }
public bool confirmed { get; set; }
public List<EmailAddress> email_addresses { get; set; }
public string fax { get; set; }
public string first_name { get; set; }
public string home_phone { get; set; }
public string job_title { get; set; }
public string last_name { get; set; }
public string middle_name { get; set; }
public string prefix_name { get; set; }
public string work_phone { get; set; }
}
Note : You have to replace oAuth token, API key and List id.
Delete method based on the api document.(http://developer.constantcontact.com/docs/contacts-api/contacts-resource.html?method=DELETE)
Note : I have not tested the delete method yet.
private async Task<string> DeleteContact(string contactId)
{
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<Replace with your oAuth Token>");
using (var request = new HttpRequestMessage(System.Net.Http.HttpMethod.Delete, "https://api.constantcontact.com/v2/contacts/" + contactId + "?api_key=<Replace with your API key>"))
{
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}
}
}
catch (Exception exp)
{
//log exp here
}
return string.Empty;
}
Here is my solution for adding a contact. What I did was combine the code that Deepu provided with the Constant Contact API v2. I also had to remove async and await references because they are incompatible with VS2010. I have not tried DELETE yet...
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Net.Http;
using CTCT.Components.Contacts;
using System.Net.Http.Headers;
/// <summary>
/// Constant Contact Helper Class for POST, PUT, and DELETE
/// </summary>
public class ConstantContactHelper
{
private string _accessToken = ConfigurationManager.AppSettings["ccAccessToken"];
private Dictionary<string, System.Net.Http.HttpMethod> requestDict = new Dictionary<string, System.Net.Http.HttpMethod> {
{"GET", HttpMethod.Get},
{"POST", HttpMethod.Post},
{"PUT", HttpMethod.Put},
{"DELETE", HttpMethod.Delete}
};
private System.Net.Http.HttpMethod requestMethod = null;
private Dictionary<string, ConstantContactURI> uriDict = new Dictionary<string, ConstantContactURI> {
{"AddContact", new ConstantContactURI("contacts")},
{"AddContactList", new ConstantContactURI("lists")},
{"AddEmailCampaign", new ConstantContactURI("campaigns")},
};
private ConstantContactURI URI_Handler = new ConstantContactURI();
private ContactRequestBody RequestBody = new ContactRequestBody();
private const string messageType = "application/json";
public string jsonRequest = null;
public string responseXml = null;
public string status_code = null;
public ConstantContactHelper() {}
public ConstantContactHelper(string methodKey, string uriKey, string firstName, string lastName, string emailAddress, string listId)
{
this.requestMethod = this.requestDict[methodKey];
this.URI_Handler = this.uriDict[uriKey];
this.RequestBody = new ContactRequestBody(firstName, lastName, emailAddress, listId);
}
// Return Response as a string
public void TryRequest()
{
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", this._accessToken);
var json = Newtonsoft.Json.JsonConvert.SerializeObject(this.RequestBody.contact);
this.jsonRequest = json;
using (var request = new HttpRequestMessage(HttpMethod.Post, this.URI_Handler.fullURI))
{
request.Headers.Add("Accept", messageType);
request.Content = new StringContent(json);
request.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(messageType);
using (var response = client.SendAsync(request))
{
this.responseXml = response.Result.Content.ReadAsStreamAsync().ConfigureAwait(false).ToString();
this.status_code = response.Status.ToString();
}
request.Content.Dispose();
}
}
}
catch(Exception exp)
{
// Handle Exception
this.responseXml = "Unhandled exception: " + exp.ToString();
}
}
}
public class ConstantContactURI
{
private const string baseURI = "https://api.constantcontact.com/v2/";
private const string queryPrefix = "?api_key=";
private string _apiKey = ConfigurationManager.AppSettings["ccApiKey"];
public string fullURI = null;
public ConstantContactURI() {}
public ConstantContactURI(string specificPath)
{
this.fullURI = baseURI + specificPath + queryPrefix + _apiKey;
}
}
public class ContactRequestBody
{
public Contact contact = new Contact();
private List<EmailAddress> email_addresses = new List<EmailAddress>()
{
new EmailAddress{
EmailAddr = "",
Status = Status.Active,
ConfirmStatus = ConfirmStatus.NoConfirmationRequired
}
};
private List<ContactList> lists = new List<ContactList>()
{
new ContactList {Id = ""}
};
public ContactRequestBody() { }
public ContactRequestBody(string firstName, string lastName, string emailAddress, string listId)
{
this.contact.FirstName = firstName;
this.contact.LastName = lastName;
this.email_addresses[0].EmailAddr = emailAddress;
this.contact.EmailAddresses = this.email_addresses;
this.lists[0].Id = listId;
this.contact.Lists = this.lists;
}
}
An Example call from an aspx.cs page looks like this:
ConstantContactHelper requestHelper = new ConstantContactHelper("POST", "AddContact", firstName.Text, lastName.Text, emailBox.Text, listId);
requestHelper.TryRequest();
lbTest.Text = requestHelper.jsonRequest + ", status code:" + requestHelper.status_code + ", xml:" + requestHelper.responseXml;
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.