1: public class AzureBlobFileSystemAgent : IFileSystemAgent
2: {
3: private static string CST_DEFAULTCONTAINERNAME = "default";
4: private static string CST_DEFAULTACCOUNTSETTING = "DataConnectionString";
5:
6: private string _containerName { get; set; }
7: private CloudStorageAccount _storageAccount { get; set; }
8:
9: private CloudBlobContainer _container;
10:
11: public AzureBlobFileSystemAgent()
12: : this(CST_DEFAULTCONTAINERNAME, CST_DEFAULTACCOUNTSETTING)
13: {
14: }
15:
16: public AzureBlobFileSystemAgent(string containerName, string storageAccountConnectionString)
17: : this(containerName, CloudStorageAccount.FromConfigurationSetting(storageAccountConnectionString))
18: {
19: }
20:
21: public AzureBlobFileSystemAgent(string containerName, CloudStorageAccount storageAccount)
22: {
23: _containerName = containerName;
24: _storageAccount = storageAccount;
25:
26: // create the blob container for account logos if not exist
27: CloudBlobClient blobStorage = _storageAccount.CreateCloudBlobClient();
28: _container = blobStorage.GetContainerReference(_containerName);
29: _container.CreateIfNotExist();
30:
31: // configure blob container for public access
32: BlobContainerPermissions permissions = _container.GetPermissions();
33: permissions.PublicAccess = BlobContainerPublicAccessType.Container;
34: _container.SetPermissions(permissions);
35: }
36:
37: #region IFileSystemAgent Members
38:
39: public void Save(Stream fileStream, string filename, bool overwrite)
40: {
41: var bytes = new byte[fileStream.Length];
42: fileStream.Read(bytes, 0, bytes.Length);
43:
44: Save(bytes, filename, overwrite);
45: }
46:
47: public void Save(byte[] bytes, string filename, bool overwrite)
48: {
49: filename = TranslateFileName(filename);
50: CloudBlockBlob blob = _container.GetBlockBlobReference(filename);
51: if (Exists(filename))
52: {
53: if (overwrite)
54: {
55: Delete(filename);
56: }
57: else
58: {
59: throw new ApplicationException(string.Format("Existed file {0} please select another name or set the overwrite = true."));
60: }
61: }
62: blob.UploadByteArray(bytes, new BlobRequestOptions() { Timeout = TimeSpan.FromMinutes(3) });
63: }
64:
65: public byte[] Load(string filename)
66: {
67: filename = TranslateFileName(filename);
68: CloudBlockBlob blob = _container.GetBlockBlobReference(filename);
69: return blob.DownloadByteArray();
70: }
71:
72: public bool Exists(string filename)
73: {
74: filename = TranslateFileName(filename);
75: CloudBlockBlob blob = _container.GetBlockBlobReference(filename);
76: try
77: {
78: blob.FetchAttributes();
79: return true;
80: }
81: catch (StorageClientException ex)
82: {
83: if (ex.ErrorCode == StorageErrorCode.ResourceNotFound)
84: {
85: return false;
86: }
87: else
88: {
89: throw;
90: }
91: }
92: }
93:
94: public void Delete(string filename)
95: {
96: filename = TranslateFileName(filename);
97: CloudBlockBlob blob = _container.GetBlockBlobReference(filename);
98: blob.DeleteIfExists();
99: }
100:
101: private string TranslateFileName(string filename)
102: {
103: return filename.Replace('/', '~').Replace('\\', '`');
104: }
105:
106: public string GetResourceUrl(string filename)
107: {
108: // when using the local storage simulator the blob enpoint without the end '/'
109: // but when using the azure it has '/' at the end of it
110: // so here i have to use Path.Combine to construct the path and then replace the '\' back to '/'
111: var url = Path.Combine(_storageAccount.BlobEndpoint.ToString(), _containerName, TranslateFileName(filename));
112: return url.Replace('\\', '/');
113: }
114:
115: #endregion
116: }