using System; using System.Collections; using System.Xml; using System.IO; using System.Net; using System.Diagnostics; using System.Data; namespace WmTransIp{ /// /// WMIT TransIP API .NET Library /// (c) Willem L. Middelkoop /// 10 february 2007 /// public class WmTransIp{ protected static string transIpApiUrl = "https://www.transip.nl/api/xml"; protected static string nsRequestUrl = "http://www.transip.nl/api/xsd/request.xsd"; protected static string nsResponseUrl = "http://www.transip.nl/api/xsd/response.xsd"; protected static bool testMode = false; #region Credentials TransIP account protected static string password = "YOUR_TRANSIP_PASSWORD"; protected static string username = "YOUR_TRANSIP_USERNAME"; #endregion protected static DataSet cachedDomainChecks = null; /// /// Will process a request (register or transfer) for a domainname /// will return true if request was accepted by Transip. For details of last status + statusmessage /// use the request object reference /// /// /// public static bool requestDomainName(ref DomainRequest request){ if(request.Whois==null || request.Nameservers == null){ return false; } HttpWebRequest httpRequest = (HttpWebRequest) WebRequest.Create(transIpApiUrl); httpRequest.Method = "POST"; httpRequest.ContentType = "text/xml"; Stream requestStream = httpRequest.GetRequestStream(); XmlTextWriter writer = new XmlTextWriter(requestStream,System.Text.Encoding.UTF8); writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); writer.WriteStartElement("transip",nsRequestUrl); writeMetaElement(writer,null); writer.WriteStartElement("request"); writeProductionMode(writer); writer.WriteElementString("type","domain"); if(request.IsTransfer){ writer.WriteElementString("subtype","transfer"); }else{ writer.WriteElementString("subtype","register"); } writer.WriteStartElement("parameters"); writer.WriteStartElement("domain"); writer.WriteElementString("domain",request.DomainName); request.Nameservers.writeDomainNameserversToXml(writer,false,true); request.Whois.writeWhoisToXml(writer,request.IsTransfer); writer.WriteEndElement(); // end of domain writer.WriteEndElement(); // end of parameters writer.WriteEndElement(); // end of request writer.WriteEndDocument(); // end of transip and closes document writer.Close(); // bool returnValue = false; HttpWebResponse httpResponse = (HttpWebResponse) httpRequest.GetResponse(); XmlTextReader reader = new XmlTextReader(httpResponse.GetResponseStream()); while(reader.Read()){ reader.MoveToElement(); if(reader.NodeType == XmlNodeType.Element){ if(reader.Name.Equals("status")){ if(reader.ReadString().ToLower().Equals("ok")){ returnValue = true; }else{ returnValue = false; } } if(reader.Name.Equals("code")){ request.LastStatusCode = int.Parse(reader.ReadString()); } if(reader.Name.Equals("description")){ request.LastStatusMessage = reader.ReadString(); } if(reader.Name.Equals("invoiceCreated")){ request.TransipInvoice = reader.ReadString(); } } } reader.Close(); httpResponse.Close(); return returnValue; } public static string[] getRegisteredDomains() { HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(transIpApiUrl); httpRequest.Method = "POST"; httpRequest.ContentType = "text/xml"; Stream requestStream = httpRequest.GetRequestStream(); XmlTextWriter writer = new XmlTextWriter(requestStream, System.Text.Encoding.UTF8); writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); writer.WriteStartElement("transip", nsRequestUrl); writeMetaElement(writer, null); writer.WriteStartElement("request"); writeProductionMode(writer); writer.WriteElementString("type", "list"); writer.WriteElementString("subtype", ""); writer.WriteEndElement(); // end of request writer.WriteEndDocument(); // end of transip and closes document writer.Close(); // HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse(); XmlTextReader reader = new XmlTextReader(httpResponse.GetResponseStream()); ArrayList domains = new ArrayList(); while (reader.Read()) { reader.MoveToElement(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name.Equals("domain")) { domains.Add(reader.ReadString()); } } } reader.Close(); httpResponse.Close(); return (string[])domains.ToArray(typeof(string)); } /// /// Will create a cache dataset, or remove old entries. Call this before using the cache! /// protected static void checkDomainCheckCache(){ if(cachedDomainChecks == null){ // create check table cachedDomainChecks = new DataSet("cacheddomainchecks"); DataTable checks = new DataTable("checks"); checks.Columns.Add(new DataColumn("domain",typeof(string))); checks.Columns.Add(new DataColumn("available",typeof(bool))); checks.Columns.Add(new DataColumn("checked",typeof(DateTime))); cachedDomainChecks.Tables.Add(checks); }else{ // remove old checks DataRow[] oldChecks = cachedDomainChecks.Tables["checks"].Select("checked<'"+DateTime.Now.AddMinutes(-30)+"'"); foreach(DataRow oldCheck in oldChecks){ oldCheck.Delete(); } cachedDomainChecks.AcceptChanges(); } } /// /// Check domain names from caches, and returnes if all domains were checked using the cache /// if this function returns true, then a call to TransIP is not required. /// /// /// protected static bool checkDomainNamesFromCache(ref DomainCheck[] domainChecks){ bool checkedAll = true; foreach(DomainCheck domainCheck in domainChecks){ checkDomainFromCache(domainCheck); if(!domainCheck.IsChecked){ checkedAll = false; } } return checkedAll; } /// /// Will check all domain names specified, and set result attributes. Checks are either performed live or using the check cache /// /// public static void checkDomainNames(ref DomainCheck[] domainChecks){ checkDomainCheckCache(); if(!checkDomainNamesFromCache(ref domainChecks)){ HttpWebRequest httpRequest = (HttpWebRequest) WebRequest.Create(transIpApiUrl); httpRequest.Method = "POST"; httpRequest.ContentType = "text/xml"; Stream requestStream = httpRequest.GetRequestStream(); XmlTextWriter writer = new XmlTextWriter(requestStream,System.Text.Encoding.UTF8); writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); writer.WriteStartElement("transip",nsRequestUrl); writeMetaElement(writer,null); writer.WriteStartElement("request"); writeProductionMode(writer); writer.WriteElementString("type","check"); writer.WriteElementString("subtype",null); writer.WriteStartElement("parameters"); writer.WriteStartElement("check"); foreach(DomainCheck domainCheck in domainChecks){ if(!domainCheck.IsChecked){ writer.WriteElementString("domain",domainCheck.DomainName); } } writer.WriteEndElement(); // end of check writer.WriteEndElement(); // end of parameters writer.WriteEndElement(); // end of request writer.WriteEndDocument(); // end of transip and closes document writer.Close(); // HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse(); XmlTextReader reader = new XmlTextReader(httpResponse.GetResponseStream()); while(reader.Read()){ reader.MoveToElement(); if(reader.NodeType == XmlNodeType.Element){ if(reader.Name.Equals("status")){ if(!reader.ReadString().ToLower().Equals("ok")){ // Somehow, the response status was not okay, halt and return to quit processing response. Trace.WriteLine("Check Domains: Unexpected response."); break; } } if(reader.Name.Equals("domain")){ string domainName = reader.ReadString(); reader.Read(); string availableStr = reader.ReadString(); bool available = availableStr.ToLower().Equals("yes"); setCheckStatus(domainChecks,domainName,available); } } } reader.Close(); httpResponse.Close(); } } /// /// Check Domain using Cache /// /// /// protected static bool checkDomainFromCache(DomainCheck check){ DataRow[] result = cachedDomainChecks.Tables["checks"].Select("domain='"+check.DomainName+"'"); if(result.Length==1){ Trace.WriteLine("Result for "+check.DomainName+" came out of the cache!"); check.IsChecked = true; check.IsAvailable = (bool) result[0]["available"]; } return check.IsChecked; } /// /// Set correct status of a check result, by looking up the right check in the array and setting values /// /// /// /// protected static void setCheckStatus(DomainCheck[] domainChecks, string domainName, bool available){ foreach(DomainCheck check in domainChecks){ if(check.DomainName.Equals(domainName)){ check.IsAvailable = available; check.IsChecked = true; DataRow newCachedCheck = cachedDomainChecks.Tables["checks"].NewRow(); newCachedCheck["domain"] = domainName; newCachedCheck["available"] = available; newCachedCheck["checked"] = DateTime.Now; cachedDomainChecks.Tables["checks"].Rows.Add(newCachedCheck); cachedDomainChecks.Tables["checks"].AcceptChanges(); break; } } } /// /// Simplefied function for single domainname check, please use other functions to check multiple domainnames, /// so they can be combined in one HTTP request /// /// /// public static bool isDomainAvailable(string domainName){ DomainCheck checkDomain = new DomainCheck(domainName); checkDomainName(ref checkDomain); return checkDomain.IsAvailable; } /// /// Function to check only one domain name. Use this to check if the status could be checked by reading the isChecked /// attribute of DomainCheck. /// /// public static void checkDomainName(ref DomainCheck checkDomain){ DomainCheck[] checkDomains = new DomainCheck[1]; checkDomains[0] = checkDomain; checkDomainNames(ref checkDomains); } /// /// Writes correct production mode status to XML Writer /// /// protected static void writeProductionMode(XmlTextWriter writer){ string modeValue = null; if(testMode){ modeValue = "test"; }else{ modeValue = "production"; } writer.WriteElementString("mode",modeValue); } /// /// Writes the meta element, this is the element containing logon information /// /// /// protected static void writeMetaElement(XmlTextWriter writer, string userRef){ writer.WriteStartElement("meta"); writer.WriteStartElement("auth"); writer.WriteElementString("type","password"); writer.WriteElementString("user",username); writer.WriteElementString("password",password); writer.WriteEndElement(); // end of auth writer.WriteElementString("userref",userRef); writer.WriteEndElement(); // end of meta } } }