private void button1_Click(object sender, EventArgs e) { //DEBUG TESTING AuthenticationData authdata = new AuthenticationData(); //Set your credentials for basic or OAuth2 inside the parentheses //Your test code below }
private void button1_Click(object sender, EventArgs e) { //DEBUG TESTING AuthenticationData authdata = new AuthenticationData(); authdata.Username = ""; authdata.Password = ""; authdata.ApiKey = ""; }
/// <summary> /// Verify user authentication /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <exception cref="ConstantAuthenticationException">Thrown if communication error with Constant server occur /// or other related with the response from server /// or if ApiKey, Username or Password are null or empty</exception> public static void IsValidUserAuthentication(AuthenticationData authenticationData) { ValidateAuthenticationData(authenticationData); try { // try to access the Service Document resource // it will throw a WebException if Constant Contact credentials are invalid GetResponseStream(new Uri(authenticationData.AccountServiceDocumentUri), authenticationData); } catch (Exception e) { throw new ConstantAuthenticationException("Account authentication failed", e, authenticationData.Username); } }
/// <summary> /// Retrieves the collection of user Contact Lists returned by the server at current chunk Id. /// The collection is sorted by the Sort Order and it will not include the system /// predefined lists ("Active", "Removed", "DoNotEmail") /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="currentChunkId">Link to the current chunk data</param> /// <param name="nextChunkId">Link to the next chunk of data</param> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server /// or if ApiKey, Username or Password are null or empty</exception> /// <returns>The collection of user Contact Lists</returns> public static IList<ContactList> GetUserContactListCollection(AuthenticationData authenticationData, string currentChunkId, out string nextChunkId) { // get the collection of Contact Lists IList<ContactList> list = GetContactListCollection(authenticationData, currentChunkId, out nextChunkId); IList<ContactList> nonSystemList = new List<ContactList>(); foreach (ContactList contactList in list) { if (!contactList.IsSystemList) { nonSystemList.Add(contactList); } } return nonSystemList; }
/// <summary> /// Remove Contact from all Contact Lists /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="contactId">Contact Id</param> /// <exception cref="ArgumentException">Thrown if Id of specified Contact is null or empty</exception> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server or if no Contact with specified Id exists /// or if ApiKey, Username or Password are null or empty</exception> public static void RemoveContactFromAllLists(AuthenticationData authenticationData, string contactId) { ValidateAuthenticationData(authenticationData); if (string.IsNullOrEmpty(contactId)) { throw new ArgumentException("Contact Id cannot be null or empty", "contactId"); } // create the URI for specified Contact Id string completeUri = String.Format(CultureInfo.InvariantCulture, "{0}/{1}", authenticationData.AccountContactsUri, contactId); // get Contact by Id Contact contact = GetContactDetailsById(authenticationData, contactId); // consider that Contact does not needs to be updated bool needUpdate = false; if (contact.ContactLists.Count != 0) { // remove Contact from all Contact Lists contact.ContactLists.Clear(); // Contact must be updated needUpdate = true; } if (!needUpdate) { // no need to update Contact return; } // get the Atom entry for specified Contact StringBuilder data = ContactComponent.RemoveContactFromAllLists(contact, authenticationData.AccountContactsUri); try { // put the Atom entry at specified Uri PutInformation(authenticationData, new Uri(completeUri), data.ToString()); } catch (Exception e) { // possible that the Contact does not exist any more; not sure if this could happened if (string.Compare(e.Message, WebExceptionCode404Message) == 0) { throw new ConstantException(String.Format(CultureInfo.InvariantCulture, "Contact with Id '{0}' does not exist.", contactId)); } throw new ConstantException(e.Message, e); } }
/// <summary> /// Sends a Http GET request and returns the response Stream from the specified Uri address /// </summary> /// <param name="address">Uri address</param> /// <param name="authenticationData">Authentication data</param> /// <returns>Response Stream</returns> private static Stream GetResponseStream(Uri address, AuthenticationData authenticationData) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address); request.Credentials = CreateCredentialCache(address, authenticationData); request.Method = WebRequestMethods.Http.Get; // request MUST include a WWW-Authenticate request.PreAuthenticate = true; Stream stream = Stream.Null; try { HttpWebResponse response = (HttpWebResponse)request.GetResponse(); // get the response Stream stream = response.GetResponseStream(); // read the response stream and save it into a memory stream return ReadResponseStream(stream); } catch (WebException e) { if (null != e.Response) { Console.Out.WriteLine("WebException Response Headers ="); Console.Out.WriteLine(e.Response.Headers); } throw; } finally { if (stream != Stream.Null) { // close response stream; it also closes the web response stream.Close(); } } }
/// <summary> /// Delete a Contact List specified by list ID /// </summary> /// <param name="authdata">Authentication data (username, password and API Key)</param> /// <param name="listID">ID of target list to delete</param> public static void deleteList(AuthenticationData authdata, string listID) { if (string.IsNullOrEmpty(listID)) { throw new ArgumentException("List Id cannot be null or empty", "id"); } try { httpDelete(authdata, authdata.AccountContactListsUri + "/" + listID); } catch (Exception e) { if (string.Compare(e.Message, WebExceptionCode404Message) == 0) { throw new ConstantException(String.Format(CultureInfo.InvariantCulture, "List with ID '{0}' does not exist.", listID)); } throw new ConstantException(e.Message, e); } }
/// <summary> /// Sends a Http DELETE request at the specified Uri address /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="address">Uri address</param> private static void DeleteInformation(AuthenticationData authenticationData, Uri address) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address); request.Credentials = CreateCredentialCache(address, authenticationData); request.Method = "DELETE"; HttpWebResponse response = null; try { response = (HttpWebResponse)request.GetResponse(); Console.WriteLine(String.Format(CultureInfo.InvariantCulture, "Method {0}, response description: {1}", request.Method, response.StatusDescription)); } finally { if (response != null) { // close the response response.Close(); } } }
/// <summary> /// Sends a Http request on specified Uri address and returns the response Stream /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="address">Uri address</param> /// <param name="requestMethod">Type of Http request</param> /// <param name="contentType">Content type of the Http request</param> /// <param name="data">Data to be send at specified Uri address</param> /// <returns>Response Stream</returns> private static Stream GetResponseStream(AuthenticationData authenticationData, Uri address, string requestMethod, string contentType, string data) { // get data bytes byte[] dataByte = Encoding.ASCII.GetBytes(data); // send the request and return the response Stream return GetResponseStream(authenticationData, address, requestMethod, contentType, dataByte); }
/// <summary> /// Opting-out ("Unsubscribe") a Contact /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="contactId">Contact Id</param> /// <exception cref="ArgumentException">Thrown if Id of specified Contact is null or empty</exception> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server or if no Contact with specified Id exists /// or if ApiKey, Username or Password are null or empty</exception> /// <remarks>Opted-out Contacts become members of the Do-Not-Mail special list</remarks> public static void UnsubscribeContact(AuthenticationData authenticationData, string contactId) { ValidateAuthenticationData(authenticationData); if (string.IsNullOrEmpty(contactId)) { throw new ArgumentException("Contact Id cannot be null or empty", "contactId"); } // create the URI for specified Contact List Id string completeUri = String.Format(CultureInfo.InvariantCulture, "{0}/{1}", authenticationData.AccountContactsUri, contactId); try { // issue a Http DELETE and specified Uri DeleteInformation(authenticationData, new Uri(completeUri)); } catch (Exception e) { // possible that the Contact does not exist any more if (string.Compare(e.Message, WebExceptionCode404Message) == 0) { throw new ConstantException(String.Format(CultureInfo.InvariantCulture, "Contact with Id '{0}' does not exist.", contactId)); } throw new ConstantException(e.Message, e); } }
/// <summary> /// Update a Contact using the simplified form. Only the following fields will be updated: /// EmailAddress, FirstName, LastName, MiddleName, HomePhone, Addr1, Addr2, Addr3, /// City, StateCode, StateName, CountryCode, CountryName, PostalCode, SubPostalCode /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="contact">Contact to be updated</param> /// <exception cref="ArgumentNullException">Thrown if specified Contact is null</exception> /// <exception cref="ArgumentException">Thrown if Id or Email Address of specified Contact is null or empty</exception> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server, if no Contact with specified Id exists /// or if Contact cannot be updated (it belongs to the Do-Not-Mail list) /// or if ApiKey, Username or Password are null or empty</exception> public static void UpdateContactSmallForm(AuthenticationData authenticationData, Contact contact) { UpdateContact(authenticationData, contact, false); }
/// <summary> /// Gets a list of email campaigns filtered by status /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="status">campaign status</param> /// <returns>filtered email campaigns</returns> public static List<EmailCampaign> GetEmailCampaignCollection(AuthenticationData authenticationData, string status) { string currentAddress = string.Format("{0}?status={1}", authenticationData.AccountEmailCampaignsListUri, status); Stream stream = Stream.Null; try { // get the response stream stream = GetResponseStream(new Uri(currentAddress), authenticationData); // parse the stream and get a collection of Contact Lists return EmailCampaignComponent.GetEmailCampaignCollection(stream); } catch (Exception e) { throw new ConstantException(e.Message, e); } finally { // close the response stream stream.Close(); } }
/// <summary> /// Retrieves the first chunk collection of Contacts that match specified Email Addresses /// </summary> /// <remarks>Constant Contact server provides paged collections</remarks> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="emailAddresses">One or more Email Addresses</param> /// <param name="nextChunkId">Link to the next chunk of data</param> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server /// or if ApiKey, Username or Password are null or empty</exception> /// <returns>The collection of Contacts</returns> public static IList<Contact> SearchContactByEmail(AuthenticationData authenticationData, IEnumerable<string> emailAddresses, out string nextChunkId) { ValidateAuthenticationData(authenticationData); return SearchContactByEmail(authenticationData, emailAddresses, null, out nextChunkId); }
/// <summary> /// Get EmailCampaign By Id /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="id">campaign id</param> /// <returns>Email campaign with the specified id</returns> public static EmailCampaign GetEmailCampaignById(AuthenticationData authenticationData, string id) { string currentAddress = string.Format("{0}/{1}", authenticationData.AccountEmailCampaignsListUri, id); Stream stream = Stream.Null; try { // get the response stream stream = GetResponseStream(new Uri(currentAddress), authenticationData); // parse the stream and get an Email Campaign return EmailCampaignComponent.GetEmailCampaign(stream); } catch (Exception e) { throw new ConstantException(e.Message, e); } finally { // close the response stream stream.Close(); } }
/// <summary> /// Get details of activity with specified ID /// </summary> /// <param name="Authdata">Authentication Data</param> /// <param name="id">ID of target activity</param> /// <returns>Returns details of activity of specified id</returns> public static Activity getActivityDetails(AuthenticationData Authdata, string id) { //verify id was specified if (string.IsNullOrEmpty(id)) { throw new ArgumentException("Activity Id cannot be null or empty", "id"); } string blank = ""; string fullcall = Authdata.accountActivitiesUri + "/" + id; //return Activity return getActivities(Authdata, id, out blank)[0]; }
/// <summary> /// Gets chunk of activites at specified link /// </summary> /// <param name="Authdata">Authentication Data</param> /// <param name="link">Link to target chunk of data</param> /// <param name="nextChunk">out link to next chunk of data</param> /// <returns>returns list up to 50 activities of specified chunk. if more than 50, out nextChunk link to next chunk of data</returns> public static IList<Activity> getActivities(AuthenticationData Authdata, string link, out string nextChunk) { //Create new xmldocument, create activitieslist uri, GET, load XML. XmlDocument xDoc = new XmlDocument(); string URI = ""; if (link == "") { URI = Authdata.accountActivitiesUri; } else { URI = Authdata.ApiRootUri + link; } try { xDoc.LoadXml(Utility.httpGet(Authdata, URI)); //Define namespaces XmlNamespaceManager xnsmgr = new XmlNamespaceManager(xDoc.NameTable); xnsmgr.AddNamespace("ns1", "http://www.w3.org/2005/Atom"); xnsmgr.AddNamespace("ns2", "http://ws.constantcontact.com/ns/1.0/"); //Check for link to next chunk of data. If no next chunk, return empty string. nextChunk = ""; XmlNodeList xnlLinks = xDoc.SelectNodes("//ns1:link", xnsmgr); foreach (XmlNode xnLink in xnlLinks) { if (xnLink.Attributes["rel"] != null) { if (xnLink.Attributes["rel"].Value == "next") { nextChunk = xnLink.Attributes["href"].Value; } } } //Select nodes XmlNodeList xnlActivities = xDoc.SelectNodes("//ns2:Activity", xnsmgr); //parse XML IList<Activity> Activities = new List<Activity>(); foreach (XmlNode xnMember in xnlActivities) { Activity activity = new Activity(); XmlNode xnName = xnMember.SelectSingleNode("../../ns1:title", xnsmgr); activity.activityName = xnName.InnerText; XmlNode xnID = xnMember.SelectSingleNode("../../ns1:id", xnsmgr); activity.activityId = xnID.InnerText; XmlNode xnUpdated = xnMember.SelectSingleNode("../../ns1:updated", xnsmgr); activity.updated = xnUpdated.InnerText; XmlNode xnLink = xnMember.SelectSingleNode("../../ns1:link", xnsmgr); activity.activityLink = xnLink.Attributes["href"].Value; XmlNode xnType = xnMember.SelectSingleNode("ns2:Type", xnsmgr); activity.Type = xnType.InnerText; XmlNode xnStatus = xnMember.SelectSingleNode("ns2:Status", xnsmgr); activity.Status = xnStatus.InnerText; XmlNode xnTransactions = xnMember.SelectSingleNode("ns2:TransactionCount", xnsmgr); activity.transactionCount = xnTransactions.InnerText; XmlNode xnErrors = xnMember.SelectSingleNode("ns2:Errors", xnsmgr); activity.Errors = xnErrors.InnerText; XmlNode xnRunStart = xnMember.SelectSingleNode("ns2:RunStartTime", xnsmgr); activity.runStartTime = xnRunStart.InnerText; XmlNode xnRunFinish = xnMember.SelectSingleNode("ns2:RunFinishTime", xnsmgr); activity.runFinishTime = xnRunFinish.InnerText; XmlNode xnInsert = xnMember.SelectSingleNode("ns2:InsertTime", xnsmgr); activity.insertTime = xnInsert.InnerText; Activities.Add(activity); } return Activities; } catch (Exception e) { if (string.Compare(e.Message, WebExceptionCode404Message) == 0) { throw new ConstantException(String.Format(CultureInfo.InvariantCulture, "Activity at link '{0}' does not exist.", link)); } throw new ConstantException(e.Message, e); } }
/// <summary> /// Gets first chunk of all activities /// </summary> /// <param name="Authdata">Authentication Data</param> /// <param name="nextChunk">Out Link to next chunk of data if</param> /// <returns>returns list up to 50 first activities. if more than 50, out nextChunk link to next chunk of data</returns> public static IList<Activity> getActivities(AuthenticationData Authdata, out string nextChunk) { return getActivities(Authdata, "", out nextChunk); }
/// <summary> /// Creates export all contacts activity for targeded list. /// </summary> /// <param name="authdata">Authenticatoin Data</param> /// <param name="listId">ID of target list</param> /// <param name="fileType">Export File Type (TXT or CSV)</param> /// <param name="exportOptDate">if add/remove date is included in file</param> /// <param name="exportOptSource">if add/removed by (contact or site owner) is included</param> /// <param name="exportListName">if name of list is included in file</param> /// <param name="sortBy">sort by Email Address in Ascending Order (EMAIL_ADDRESS) or Date in Descending Order (DATE_DESC)</param> /// <param name="columns">List of what columns to include in exported file</param> /// <returns>Calls urlEncodedPost, which returns the response from server after HTTP POST</returns> public static string exportContacts(AuthenticationData authdata, int listId, string fileType, bool exportOptDate, bool exportOptSource, bool exportListName, string sortBy, IList<string> columns) { fileType = fileType.ToUpper(); sortBy = sortBy.ToUpper(); if (fileType != "TXT") { if (fileType != "CSV") { throw new ArgumentException("File Type Must be CSV or TXT", "fileType"); } } if (sortBy != "EMAIL_ADDRESS") { if (fileType != "DATE_DESC") { throw new ArgumentException("Invalid Sort By Type Specified (must be DATE_DESC or EMAIL_ADDRESS)", "sortBy"); } } string uri = authdata.accountActivitiesUri; string options = "activityType=EXPORT_CONTACTS&fileType=" + fileType + "&exportOptDate=" + exportOptDate.ToString() + "&exportOptSource=" + exportOptSource.ToString() + "&exportListName=" + exportListName.ToString() + "&sortBy=" + sortBy; string calldata = ""; int i; for (i = 0; i < columns.Count; i++) { string thisline = columns[i]; thisline = HttpUtility.UrlEncode(thisline); calldata = calldata + "&columns=" + thisline; } string targetlist = authdata.AccountContactListsUri + "/" + listId.ToString(); targetlist = HttpUtility.UrlEncode(targetlist); string fullrequest = options + calldata + "&listId=" + targetlist; try { return Utility.urlEncodedPost(authdata, uri, fullrequest); } catch (Exception e) { if (string.Compare(e.Message, WebExceptionCode404Message) == 0) { throw new ConstantException(String.Format(CultureInfo.InvariantCulture, "List with ID of '{0}' does not exist.", listId)); } throw new ConstantException(e.Message, e); } }
/// <summary> /// Retrieves the collection of Contacts that match specified Email Addresses, returned by the server at current chunk Id. /// Entire collection of Contacts will be returned if no Email Address is specified /// </summary> /// <remarks>Constant Contact server provides paged collections</remarks> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="emailAddresses">One or more Email Addresses</param> /// <param name="currentChunkId">Link to the current chunk data</param> /// <param name="nextChunkId">Link to the next chunk of data</param> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server /// or if ApiKey, Username or Password are null or empty</exception> /// <returns>The collection of Contacts</returns> public static List<Contact> SearchContactByEmail(AuthenticationData authenticationData, IEnumerable<string> emailAddresses, string currentChunkId, out string nextChunkId) { if (null == emailAddresses) { throw new ArgumentNullException("emailAddresses"); } // create the Uri address with the Email address query StringBuilder uriAddress = new StringBuilder(); uriAddress.Append(authenticationData.AccountContactsUri); uriAddress.Append("?"); // loop the Email Address and create the query foreach (string email in emailAddresses) { uriAddress.AppendFormat("email={0}&", HttpUtility.UrlEncode(email.ToLower(CultureInfo.CurrentCulture))); } // remove the last '&' character from the query uriAddress.Remove(uriAddress.Length - 1, 1); string currentAddress = String.Format(CultureInfo.InvariantCulture, "{0}{1}", uriAddress, currentChunkId); Stream stream = Stream.Null; try { // get the response stream stream = GetResponseStream(new Uri(currentAddress), authenticationData); // parse the stream and get a collection of Contacts return ContactComponent.GetContactCollection(stream, out nextChunkId); } catch (Exception e) { throw new ConstantException(e.Message, e); } finally { // close the response stream stream.Close(); } }
/// <summary> /// Update a Contact /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="contact">Contact to be updated</param> /// <param name="fullUpdate">True if all Contact fields will be update; False otherwise (only the following fields /// will be updated: EmailAddress, FirstName, LastName, MiddleName, HomePhone, Addr1, Addr2, Addr3, /// City, StateCode, StateName, CountryCode, CountryName, PostalCode, SubPostalCode)</param> /// <exception cref="ArgumentNullException">Thrown if specified Contact is null</exception> /// <exception cref="ArgumentException">Thrown if Id or Email Address of specified Contact is null or empty</exception> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server, if no Contact with specified Id exists /// or if Contact cannot be updated (it belongs to the Do-Not-Mail list) /// or if ApiKey, Username or Password are null or empty</exception> private static void UpdateContact(AuthenticationData authenticationData, Contact contact, bool fullUpdate) { ValidateAuthenticationData(authenticationData); if (null == contact) { throw new ArgumentNullException("contact"); } if (string.IsNullOrEmpty(contact.Id)) { throw new ArgumentException("Contact Id cannot be null or empty", "contact"); } if (string.IsNullOrEmpty(contact.EmailAddress)) { throw new ArgumentException("Contact Email Address cannot be null or empty", "contact"); } // create the URI for specified Contact Id string completeUri = String.Format(CultureInfo.InvariantCulture, "{0}{1}", AuthenticationData.HostAddress, contact.Link); // get the Atom entry for specified Contact StringBuilder data = ContactComponent.UpdateContact(contact, authenticationData.ApiRootUri, authenticationData.AccountContactListsUri, fullUpdate); try { // put the Atom entry at specified Uri PutInformation(authenticationData, new Uri(completeUri), data.ToString()); } catch (Exception e) { if (string.Compare(e.Message, WebExceptionCode404Message) == 0) { throw new ConstantException(String.Format(CultureInfo.InvariantCulture, "Contact with Id '{0}' does not exist.", contact.Id)); } if (string.Compare(e.Message, WebExceptionCode403Message) == 0) { throw new ConstantException("Contact cannot be updated. It belongs to the Do-Not-Mail list."); } throw new ConstantException(e.Message, e); } }
/// <summary> /// Update a Contact using the full form. All Contact fields will be updated /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="contact">Contact to be updated</param> /// <exception cref="ArgumentNullException">Thrown if specified Contact is null</exception> /// <exception cref="ArgumentException">Thrown if Id or Email Address of specified Contact is null or empty</exception> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server, if no Contact with specified Id exists /// or if Contact cannot be updated (it belongs to the Do-Not-Mail list) /// or if ApiKey, Username or Password are null or empty</exception> public static void UpdateContactFullForm(AuthenticationData authenticationData, Contact contact) { UpdateContact(authenticationData, contact, true); }
/// <summary> /// Check if API Key, Username and Password are not null or empty /// </summary> /// <param name="authenticationData">Authentication data to be validated</param> /// <exception cref="ConstantException">Thrown if API Key, Username or Password are null or empty</exception> private static void ValidateAuthenticationData(AuthenticationData authenticationData) { if (string.IsNullOrEmpty(authenticationData.Username)) { throw new ConstantException("Username cannot be null or empty"); } if (string.IsNullOrEmpty(authenticationData.Password)) { throw new ConstantException("Password cannot be null or empty"); } if (string.IsNullOrEmpty(authenticationData.ApiKey)) { throw new ConstantException("API Key cannot be null or empty"); } }
/// <summary> /// Create credentials for network transport /// </summary> /// <param name="address">Uri address</param> /// <param name="authenticationData">Authentication data</param> /// <returns>The Credentials for specified Uri address</returns> private static ICredentials CreateCredentialCache(Uri address, AuthenticationData authenticationData) { NetworkCredential networkCred = new NetworkCredential(authenticationData.AccountUserName, authenticationData.Password); CredentialCache cacheCred = new CredentialCache(); cacheCred.Add(address, "Basic", networkCred); return cacheCred; }
/// <summary> /// Create a New Contact /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="contact">Contact to be created</param> /// <remarks>The POST data presents only values for EmailAddress, FirstName, LastName, OptInSource and ContactLists elements</remarks> /// <exception cref="ArgumentNullException">Thrown if specified Contact is null</exception> /// <exception cref="ArgumentException">Thrown if E-mail Address of specified Contact is null or empty</exception> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server or if specified Contact does not belongs to any list /// or if ApiKey, Username or Password are null or empty</exception> /// <returns>Newly created Contact</returns> public static Contact CreateNewContact(AuthenticationData authenticationData, Contact contact) { ValidateAuthenticationData(authenticationData); if (null == contact) { throw new ArgumentNullException("contact"); } if (string.IsNullOrEmpty(contact.EmailAddress)) { throw new ArgumentException("Contact E-mail Address cannot be null or empty", "contact"); } if (null == contact.ContactLists || contact.ContactLists.Count == 0) { throw new ConstantException("Contact does not belongs to any contact list"); } // get the Atom entry for specified Contact StringBuilder data = ContactComponent.CreateNewContact(contact, authenticationData.AccountContactListsUri); Stream stream = Stream.Null; try { // post the Atom entry at specified Uri and save the response stream stream = PostInformation(authenticationData, new Uri(authenticationData.AccountContactsUri), data.ToString()); // return newly created Contact return ContactComponent.GetContactDetails(stream); } catch (Exception e) { throw new ConstantException(e.Message, e); } finally { // close the response stream stream.Close(); } }
/// <summary> /// Retrieves the collection of Contact Lists returned by the server at current chunk Id. /// The collection is sorted by the Sort Order and it will include the system /// predefined lists ("Active", "Removed", "DoNotEmail") /// </summary> /// <remarks>Constant Contact server provides paged collections</remarks> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="currentChunkId">Link to the current chunk data</param> /// <param name="nextChunkId">Link to the next chunk of data</param> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server /// or if ApiKey, Username or Password are null or empty</exception> /// <returns>The collection of Contact Lists</returns> private static IList<ContactList> GetContactListCollection(AuthenticationData authenticationData, string currentChunkId, out string nextChunkId) { string currentAddress = String.Format(CultureInfo.InvariantCulture, "{0}{1}", authenticationData.AccountContactListsUri, currentChunkId); Stream stream = Stream.Null; try { // get the response stream stream = GetResponseStream(new Uri(currentAddress), authenticationData); // parse the stream and get a collection of Contact Lists return ContactListComponent.GetContactListsCollection(stream, out nextChunkId); } catch (Exception e) { throw new ConstantException(e.Message, e); } finally { // close the response stream stream.Close(); } }
/// <summary> /// Retrieves the first chunk collection of Contacts that the server provides /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <remarks>Constant Contact server provides paged collections</remarks> /// <param name="nextChunkId">Link to the next chunk of data</param> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server /// or if ApiKey, Username or Password are null or empty</exception> /// <returns>The collection of Contacts</returns> public static IList<Contact> GetContactCollection(AuthenticationData authenticationData, out string nextChunkId) { return GetContactCollection(authenticationData, null, out nextChunkId); }
/// <summary> /// Sends a Http request on specified Uri address and returns the response Stream /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="address">Uri address</param> /// <param name="requestMethod">Type of Http request</param> /// <param name="contentType">Content type of the Http request</param> /// <param name="data">Data to be send at specified Uri address</param> /// <returns>Response Stream</returns> private static Stream GetResponseStream(AuthenticationData authenticationData, Uri address, string requestMethod, string contentType, byte[] data) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address); request.Credentials = CreateCredentialCache(address, authenticationData); request.Method = requestMethod; // set the content type of the data being posted request.ContentType = contentType; // request MUST include a WWW-Authenticate request.PreAuthenticate = true; // set the content length of the data being posted request.ContentLength = data.Length; // write data Stream stream = request.GetRequestStream(); stream.Write(data, 0, data.Length); Stream responseStream = Stream.Null; try { // get the response Stream HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Console.WriteLine(String.Format(CultureInfo.InvariantCulture, "Method {0}, response description: {1}", request.Method, response.StatusDescription)); if (response.StatusCode == HttpStatusCode.NoContent) { // server don't send any response to us return Stream.Null; } // get the response Stream responseStream = response.GetResponseStream(); // read the response stream and save it into a memory stream MemoryStream memoryStream = ReadResponseStream(responseStream); return memoryStream; } finally { // close the Stream object stream.Close(); // close response stream; it also closes the web response responseStream.Close(); } }
/// <summary> /// Retrieve an individual Contact by its Id /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="id">Contact Id</param> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server or if no Contact with specified Id exists /// or if ApiKey, Username or Password are null or empty</exception> /// <returns>Contact with specified Id</returns> public static Contact GetContactDetailsById(AuthenticationData authenticationData, string id) { ValidateAuthenticationData(authenticationData); if (string.IsNullOrEmpty(id)) { throw new ArgumentException("Contact Id cannot be null or empty", "id"); } // create the URI for specified Contact Id string completeUri = String.Format(CultureInfo.InvariantCulture, "{0}/{1}", authenticationData.AccountContactsUri, id); // get the response stream Stream stream = Stream.Null; try { stream = GetResponseStream(new Uri(completeUri), authenticationData); // parse the stream and obtain a Contact object return ContactComponent.GetContactDetails(stream); } catch (Exception e) { if (string.Compare(e.Message, WebExceptionCode404Message) == 0) { throw new ConstantException(String.Format(CultureInfo.InvariantCulture, "Contact with Id '{0}' does not exist.", id)); } throw new ConstantException(e.Message, e); } finally { // close the response stream stream.Close(); } }
/// <summary> /// PUT the data at the specified Uri address. /// Constant Contact server will not send any response /// </summary> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="address">Uri address</param> /// <param name="data">Data to be send at specified Uri address</param> private static void PutInformation(AuthenticationData authenticationData, Uri address, string data) { // set the Http request content type const string contentType = @"application/atom+xml"; // send a Http PUT request and return the response Stream GetResponseStream(authenticationData, address, WebRequestMethods.Http.Put, contentType, data); }
/// <summary> /// Retrieves the first chunk collection of user Contact Lists that the server provides /// for current Contact Account Owner. /// The collection is sorted by the Sort Order and it will not include the system /// predefined lists ("Active", "Removed", "DoNotEmail") /// </summary> /// <remarks>Constant Contact server provides paged collections</remarks> /// <param name="authenticationData">Authentication data (username, password and API Key)</param> /// <param name="nextChunkId">Link to the next chunk data</param> /// <exception cref="ConstantException">Thrown if communication error with Constant server occur /// or other related with the response from server /// or if ApiKey, Username or Password are null or empty</exception> /// <returns>The collection of user Contact Lists</returns> public static IList<ContactList> GetUserContactListCollection(AuthenticationData authenticationData, out string nextChunkId) { ValidateAuthenticationData(authenticationData); return GetUserContactListCollection(authenticationData, null, out nextChunkId); }