title: C# & ASP.NET - Anyone create a library to talk to EdgeCast CDN via FTP?
body: <p>For one of my projects we utilize a Content Delivery Network (<a href="http://www.edgecast.com/verticals/cdn.htm?gclid=CN3UptGU0ZwCFQhV2godxXdgJw" rel="nofollow noreferrer">EdgeCast</a>) and I was wondering if anyone knew of an existing (open source) library for C# that we could leverage?  In a nutshell, I am investigating the ability to create directories, upload files, and allow some general maintenance (rename files, delete files) via our admin panel.  Any insight would be appreciated.</p>
  
  <hr>
  
  <p><strong>NOTE</strong>:  My code to do this.  I don't know if they have an updated API at this point so please check.  This code is circa 2009 (as-is, no warranties, use at your own risk, etc).  </p>
  
  <p><strong>EdgeCast.cs</strong>  </p>
  
  <pre><code>using System;
  using edgeCastWS = [DOMAIN].com.edgecast.api.EdgeCastWebServices;
  
  namespace [DOMAIN].IO.ContentDeliveryNetwork
  {
      /// &lt;summary&gt;
      /// &lt;b&gt;Authentication&lt;/b&gt;
      /// &lt;para&gt;Each web service call will include a string parameter called strCredential which will ensure that customers may only access data related to their own accounts. This credential is a string made up of a few separate pieces of information.&lt;/para&gt;
      /// &lt;para&gt;A typical credential a customer would use may look like: “c:bas:user@email.com:password”&lt;/para&gt;
      /// &lt;para&gt; * The field format of this string is delimited with a colon “:” character.&lt;/para&gt;
      /// &lt;para&gt; * The first field is the type of client which is calling the web service. “c” represents an individual customer.&lt;/para&gt;
      /// &lt;para&gt; * The second field is the security type. “bas” represents Basic Authentication.&lt;/para&gt;
      /// &lt;para&gt; * With basic authentication the third field is the username which is usually in email address notation.&lt;/para&gt;
      /// &lt;para&gt; * With basic authentication the fourth field is the password associated with the user.&lt;/para&gt;
      /// &lt;para&gt;If the username and password are not valid, then the credential will prevent the specified function from proceeding. A SOAP exception will be generated and sent back to the client that called the function. The message contained in the exception will contain the string “Access Denied.”&lt;/para&gt;
      /// &lt;/summary&gt;
      public class EdgeCast : IDisposable
      {
          #region Declarations
          [ThreadStatic]
          private static EdgeCast _current;
          private static EdgeCastCredential _credential = null;
          private static string _customerID = string.Empty;
          private static edgeCastWS _edgeCastWS = null;
          #endregion
  
          #region Constructor
          public EdgeCast()
          {
              if (_current != null)
              {
                  throw new InvalidOperationException("Only one ContentDeliveryNetwork may be created on a given thread.");
              }
              _current = this;
              _edgeCastWS = new edgeCastWS();
              ConstructCredentials();
              _customerID = AppSettings.EdgeCast_CustomerID;
          }
          #endregion
  
          #region API Methods
          /// &lt;summary&gt;
          /// Purges a file from all of the EdgeCast caching servers. This process may take a few minutes to fully complete.
          /// &lt;/summary&gt;
          /// &lt;param name="Path"&gt;This is path of the file or folder to purge, in URL format. To specify a folder, please put a trailing slash at the end of the URL. All files under that folder will be purged&lt;/param&gt;
          /// &lt;param name="MediaType"&gt;HTTP Large Object = 3, HTTP Small Object = 8, Flash = 2, Windows = 1&lt;/param&gt;
          /// &lt;returns&gt;An integer that indicates whether or not the transaction was successful. 0 represents yes, -1 represents no&lt;/returns&gt;
          internal static short PurgeFileFromEdge(string Path, int MediaType)
          {
              return _edgeCastWS.PurgeFileFromEdge(_credential.Credential, _customerID, Path, MediaType);
          }
          /// &lt;summary&gt;
          /// Loads a file to disk on all of the EdgeCast caching servers. This process may take a few minutes to fully complete.
          /// &lt;/summary&gt;
          /// &lt;param name="Path"&gt;This is path of the file to load, in URL format. Folders may not be loaded and will be ignored&lt;/param&gt;
          /// &lt;param name="MediaType"&gt;HTTP Large Object = 3, HTTP Small Object = 8&lt;/param&gt;
          /// &lt;returns&gt;An integer that indicates whether or not the transaction was successful. 0 represents yes, -1 represents no&lt;/returns&gt;
          internal static short LoadFileToEdge(string Path, int MediaType)
          {
              return _edgeCastWS.LoadFileToEdge(_credential.Credential, _customerID, Path, MediaType);
          }
          /// &lt;summary&gt;
          /// This method call is used to add a token authentication directory. All additions and changes should be processed every 30 minutes
          /// &lt;/summary&gt;
          /// &lt;param name="Dir"&gt;Directory Path should be starting from the root. Example: /directory1/directory2&lt;/param&gt;
          /// &lt;param name="MediaType"&gt;Use 1 for Windows, 2 for Flash, 3 for HTTP Caching / Progressive download.&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          internal static short TokenDirAdd(string Dir, int MediaType)
          {
              return _edgeCastWS.TokenDirAdd(_credential.Credential, _customerID, Dir, MediaType);
          }
          internal static string TokenEncrypt(string Key, string Args)
          {
              return _edgeCastWS.TokenEncrypt(_credential.Credential, Key, Args);
          }
          internal static short TokenKeyUpdate(string Key, int MediaType)
          {
              return _edgeCastWS.TokenKeyUpdate(_credential.Credential, _customerID, Key, MediaType);
          }
          #endregion
  
          #region FTP Methods
          /// &lt;summary&gt;
          /// Does a FTP Upload of a file on the local system
          /// &lt;/summary&gt;
          /// &lt;param name="targetPath"&gt;The full path to save to on the FTP server (.\Campaigns\Prod\[Company GUID])&lt;/param&gt;
          /// &lt;param name="sourceFileName"&gt;The full path and filename of the file to be uploaded (C:\[DOMAIN]\files\[filename])&lt;/param&gt;
          internal static void FTP_UploadFile(string targetPath, string sourceFileName)
          {
              string[] dirs = targetPath.Split(new char[] { '\\', '/' });
  
              using (FTPFactory myFTP = new FTPFactory())
              {
                  myFTP.login();
                  myFTP.setBinaryMode(true);
  
                  // Make sure the directories are there and change down to the bottom most directory...
                  foreach (string dirName in dirs)
                  {
                      bool dirExists = true;
                      try { myFTP.chdir(dirName); }
                      catch { dirExists = false; }
                      if (!dirExists)
                      {
                          myFTP.mkdir(dirName);
                          myFTP.chdir(dirName);
                      }
                  }
  
                  // upload the file now...
                  myFTP.upload(sourceFileName);
              }
          }
          /// &lt;summary&gt;
          /// Returns a string array of files in the target directory
          /// &lt;/summary&gt;
          /// &lt;param name="targetPath"&gt;The target directory&lt;/param&gt;
          /// &lt;returns&gt;string array or null if no files found&lt;/returns&gt;
          internal static string[] FTP_GetFileList(string targetPath)
          {
              string[] dirs = targetPath.Split(new char[] { '\\', '/' });
              string[] files = null;
  
              using (FTPFactory myFTP = new FTPFactory())
              {
                  myFTP.login();
                  myFTP.setBinaryMode(true);
  
                  // Make sure the directories are there and change down to the bottom most directory...
                  foreach (string dirName in dirs)
                  {
                      bool dirExists = true;
                      try { myFTP.chdir(dirName); }
                      catch { dirExists = false; }
                      if (!dirExists)
                      {
                          myFTP.mkdir(dirName);
                          myFTP.chdir(dirName);
                      }
                  }
  
                  // get the list of files now...
                  files = myFTP.getFileList("*.*");
              }
              return files;
          }
          /// &lt;summary&gt;
          /// Checks to see if a file exists
          /// &lt;/summary&gt;
          /// &lt;param name="targetPath"&gt;The CDN directory path to look in&lt;/param&gt;
          /// &lt;param name="targetFile"&gt;The file to look for&lt;/param&gt;
          /// &lt;returns&gt;true = found, false = not found&lt;/returns&gt;
          internal static bool FTP_DoesFileExist(string targetPath, string targetFile)
          {
              bool retFlag = true;
              string[] dirs = targetPath.Split(new char[] { '\\', '/' });
  
              using (FTPFactory myFTP = new FTPFactory())
              {
                  myFTP.login();
                  myFTP.setBinaryMode(true);
  
                  // change to the target directory - if it does not exists, neither does the file!  simple...
                  foreach (string dirName in dirs)
                  {
                      try { myFTP.chdir(dirName); }
                      catch { retFlag = false; }
                  }
                  if (retFlag)
                  {
                      try { retFlag = myFTP.getFileSize(targetFile) &gt; 0; }
                      catch { retFlag = false; }
                  }
              }
              return retFlag;
          }
          internal static bool FTP_DoesFileExist(string targetFile)
          {
              string targetPath = targetFile.Replace(@"http://", "");
              targetPath = targetPath.Replace(@"https://", "");
              targetPath = targetPath.Replace(@"cdn1.[DOMAIN].com/", "");
              targetPath = targetPath.Replace(@"/", @"\");
  
              targetPath = targetPath.Substring(0, targetPath.LastIndexOf(@"\"));
              targetFile = targetFile.Substring(targetFile.LastIndexOf(@"/") + 1);
              return FTP_DoesFileExist(targetPath, targetFile);
          }
          #endregion
  
          #region Helper Methods
          static private string ConstructCredentials()
          {
              _credential = new EdgeCastCredential();
              return _credential.Credential;
          }
          static private string ConstructCredentials(string credentials)
          {
              _credential = new EdgeCastCredential(credentials);
              return _credential.Credential;
          }
          static private string ConstructCredentials(string typeOfClient, string securityType, string userName, string password)
          {
              _credential = new EdgeCastCredential(typeOfClient, securityType, userName, password);
              return _credential.Credential;
          }
          #endregion
  
          #region IDisposable Members
          public void Dispose()
          {
              _current = null;
          }
          #endregion
      }
  }
  </code></pre>
  
  <p><strong>EdgeCastCredential.cs</strong>    </p>
  
  <pre><code>using System;
  using rivSecurity = [DOMAIN].Security.Cryptography.Internal;
  
  namespace [DOMAIN].IO.ContentDeliveryNetwork
  {
      internal class EdgeCastCredential
      {
          #region Properties
          public string TypeOfClient;
          public string SecurityType;
          public string UserName;
          public string Password;
          public string Credential { get { return String.Format("{0}:{1}:{2}:{3}", TypeOfClient, SecurityType, UserName, Password); } }
          #endregion
  
          #region Constructor
          public EdgeCastCredential()
          {
              TypeOfClient = AppSettings.EdgeCast_TypeOfClient;
              SecurityType = AppSettings.EdgeCast_SecurityType;
              UserName = rivSecurity.Decrypt(AppSettings.EdgeCast_UserName);
              Password = rivSecurity.Decrypt(AppSettings.EdgeCast_Password);
          }
          public EdgeCastCredential(string credentials)
          {
              string[] parts = credentials.Split(new char[] { ':' });
          }
          public EdgeCastCredential(string typeOfClient, string securityType, string userName, string password)
          {
              TypeOfClient = typeOfClient;
              SecurityType = securityType;
              UserName = userName;
              Password = password;
          }
          #endregion
      }
  }
  </code></pre>