Skip to content

Commit 3371643

Browse files
authored
Merge pull request #6 from tamram/master
addressed remaining comments, added example per customer request
2 parents 4453e62 + e27b7e7 commit 3371643

File tree

2 files changed

+125
-42
lines changed

2 files changed

+125
-42
lines changed

BlobStorage/Advanced.cs

Lines changed: 93 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ public static class Advanced
3636
// Prefix for containers created by the sample.
3737
private const string ContainerPrefix = "sample-";
3838

39-
// Variable for saving the user's service property settings.
40-
private static ServiceProperties properties = null;
39+
// Prefix for blob created by the sample.
40+
private const string BlobPrefix = "sample-blob-";
4141

4242
/// <summary>
4343
/// Calls the advanced samples for Blob storage.
@@ -62,7 +62,7 @@ public static async Task CallBlobAdvancedSamples()
6262
userServiceProperties = await blobClient.GetServicePropertiesAsync();
6363

6464
// Get a reference to a sample container.
65-
container = CreateSampleContainer(blobClient).Result;
65+
container = await CreateSampleContainer(blobClient);
6666

6767
// Call Blob service client samples.
6868
await CallBlobClientSamples(blobClient);
@@ -162,14 +162,20 @@ private static async Task CallContainerSamples(CloudBlobContainer container)
162162
await ManageContainerLeases(container.ServiceClient);
163163
}
164164

165-
166165
/// <summary>
167166
/// Calls samples that demonstrate how to work with blobs.
168167
/// </summary>
169168
/// <param name="container">A CloudBlobContainer object.</param>
170169
/// <returns>A Task object.</returns>
171170
private static async Task CallBlobSamples(CloudBlobContainer container)
172171
{
172+
// Create a blob with a random name.
173+
CloudBlockBlob blob = await CreateRandomlyNamedBlockBlob(container);
174+
175+
// Get a reference to the blob created above from the server.
176+
// This call will fail if the blob does not yet exist.
177+
await GetExistingBlobReference(container, blob.Name);
178+
173179
// Create a specified number of block blobs in a flat structure.
174180
await CreateSequentiallyNamedBlockBlobs(container, 5);
175181

@@ -194,7 +200,6 @@ private static async Task CallBlobSamples(CloudBlobContainer container)
194200
await UploadBlobInBlocks(container);
195201
}
196202

197-
198203
/// <summary>
199204
/// Calls shared access signature samples for both containers and blobs.
200205
/// </summary>
@@ -296,7 +301,6 @@ private static async Task ConfigureBlobAnalytics(CloudBlobClient blobClient)
296301
}
297302
}
298303

299-
300304
/// <summary>
301305
/// Gets the Blob service stats for the secondary endpoint for an RA-GRS (read-access geo-redundant) storage account.
302306
/// </summary>
@@ -430,7 +434,7 @@ private static async Task ListContainersWithPrefix(CloudBlobClient blobClient, s
430434
private static async Task<CloudBlobContainer> CreateSampleContainer(CloudBlobClient blobClient)
431435
{
432436
// Name sample container based on new GUID, to ensure uniqueness.
433-
string containerName = ContainerPrefix + Guid.NewGuid().ToString();
437+
string containerName = ContainerPrefix + Guid.NewGuid();
434438

435439
// Get a reference to a sample container.
436440
CloudBlobContainer container = blobClient.GetContainerReference(containerName);
@@ -452,7 +456,6 @@ private static async Task<CloudBlobContainer> CreateSampleContainer(CloudBlobCli
452456
return container;
453457
}
454458

455-
456459
/// <summary>
457460
/// Add some sample metadata to the container.
458461
/// </summary>
@@ -477,7 +480,6 @@ private static async Task AddContainerMetadata(CloudBlobContainer container)
477480
}
478481
}
479482

480-
481483
/// <summary>
482484
/// Sets the anonymous access level.
483485
/// </summary>
@@ -506,7 +508,6 @@ private static async Task SetAnonymousAccessLevel(CloudBlobContainer container,
506508
throw;
507509
}
508510
}
509-
510511

511512
/// <summary>
512513
/// Reads the container's properties.
@@ -532,7 +533,6 @@ private static void PrintContainerPropertiesAndMetadata(CloudBlobContainer conta
532533
Console.WriteLine();
533534
}
534535

535-
536536
/// <summary>
537537
/// Demonstrates container lease states: available, breaking, broken, and expired.
538538
/// A lease is used in each example to delete the container.
@@ -562,7 +562,7 @@ private static async Task ManageContainerLeases(CloudBlobClient blobClient)
562562
*/
563563

564564
// Lease is available on the new container. Acquire the lease and delete the leased container.
565-
container1 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid().ToString());
565+
container1 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid());
566566
await container1.CreateIfNotExistsAsync();
567567

568568
// Get container properties to see the available lease.
@@ -585,7 +585,7 @@ private static async Task ManageContainerLeases(CloudBlobClient blobClient)
585585
Case 2: Lease is breaking
586586
*/
587587

588-
container2 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid().ToString());
588+
container2 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid());
589589
await container2.CreateIfNotExistsAsync();
590590

591591
// Acquire the lease.
@@ -609,7 +609,7 @@ private static async Task ManageContainerLeases(CloudBlobClient blobClient)
609609
Case 3: Lease is broken
610610
*/
611611

612-
container3 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid().ToString());
612+
container3 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid());
613613
await container3.CreateIfNotExistsAsync();
614614

615615
// Acquire the lease.
@@ -630,7 +630,7 @@ private static async Task ManageContainerLeases(CloudBlobClient blobClient)
630630
Case 4: Lease has expired.
631631
*/
632632

633-
container4 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid().ToString());
633+
container4 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid());
634634
await container4.CreateIfNotExistsAsync();
635635

636636
// Acquire the lease.
@@ -651,7 +651,7 @@ private static async Task ManageContainerLeases(CloudBlobClient blobClient)
651651
Case 5: Attempt to delete leased container without lease ID.
652652
*/
653653

654-
container5 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid().ToString());
654+
container5 = blobClient.GetContainerReference(LeasingPrefix + Guid.NewGuid());
655655
await container5.CreateIfNotExistsAsync();
656656

657657
// Acquire the lease.
@@ -698,7 +698,6 @@ private static async Task ManageContainerLeases(CloudBlobClient blobClient)
698698
}
699699
}
700700

701-
702701
/// <summary>
703702
/// Reads the lease properties for the container.
704703
/// </summary>
@@ -756,7 +755,6 @@ private static async Task DeleteContainersWithPrefix(CloudBlobClient blobClient,
756755
}
757756
}
758757

759-
760758
/// <summary>
761759
/// Creates a shared access policy on the container.
762760
/// </summary>
@@ -769,6 +767,8 @@ private static async Task CreateSharedAccessPolicy(CloudBlobContainer container,
769767
// The access policy provides create, write, read, list, and delete permissions.
770768
SharedAccessBlobPolicy sharedPolicy = new SharedAccessBlobPolicy()
771769
{
770+
// When the start time for the SAS is omitted, the start time is assumed to be the time when the storage service receives the request.
771+
// Omitting the start time for a SAS that is effective immediately helps to avoid clock skew.
772772
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
773773
Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.List |
774774
SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Create | SharedAccessBlobPermissions.Delete
@@ -782,7 +782,6 @@ private static async Task CreateSharedAccessPolicy(CloudBlobContainer container,
782782
await container.SetPermissionsAsync(permissions);
783783
}
784784

785-
786785
/// <summary>
787786
/// Returns a URI containing a SAS for the blob container.
788787
/// </summary>
@@ -800,7 +799,8 @@ private static string GetContainerSasUri(CloudBlobContainer container, string st
800799
// to construct a shared access policy that is saved to the container's shared access policies.
801800
SharedAccessBlobPolicy adHocPolicy = new SharedAccessBlobPolicy()
802801
{
803-
// Omit SAS start time to avoid clock skew. Start time is assumed to be the time when the service receives the request.
802+
// When the start time for the SAS is omitted, the start time is assumed to be the time when the storage service receives the request.
803+
// Omitting the start time for a SAS that is effective immediately helps to avoid clock skew.
804804
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
805805
Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List
806806
};
@@ -826,7 +826,6 @@ private static string GetContainerSasUri(CloudBlobContainer container, string st
826826
return container.Uri + sasContainerToken;
827827
}
828828

829-
830829
/// <summary>
831830
/// Tests a container SAS to determine which operations it allows.
832831
/// </summary>
@@ -968,7 +967,6 @@ private static async Task TestContainerSAS(string sasUri, string blobName, strin
968967

969968
#endregion
970969

971-
972970
#region AllBlobTypeSamples
973971

974972
/// <summary>
@@ -1046,7 +1044,6 @@ private static void PrintBlobPropertiesAndMetadata(CloudBlob blob)
10461044
Console.WriteLine();
10471045
}
10481046

1049-
10501047
/// <summary>
10511048
/// Reads the virtual directory's properties.
10521049
/// </summary>
@@ -1125,7 +1122,6 @@ private static async Task ListBlobsFlatListing(CloudBlobContainer container, int
11251122
}
11261123
}
11271124

1128-
11291125
/// <summary>
11301126
/// Lists blobs in the specified container using a hierarchical listing, and calls this method recursively to return the contents of each
11311127
/// virtual directory. Reads the properties on each blob or virtual directory returned and writes them to the console window.
@@ -1189,9 +1185,78 @@ private static async Task ListBlobsHierarchicalListing(CloudBlobContainer contai
11891185

11901186
#endregion
11911187

1192-
11931188
#region BlockBlobSamples
11941189

1190+
/// <summary>
1191+
/// Creates a randomly named block blob.
1192+
/// </summary>
1193+
/// <param name="container">The container.</param>
1194+
/// <returns>A Task object.</returns>
1195+
private static async Task<CloudBlockBlob> CreateRandomlyNamedBlockBlob(CloudBlobContainer container)
1196+
{
1197+
// Get a reference to a blob that does not yet exist.
1198+
// The GetBlockBlobReference method does not make a request to the service, but only creates the object in memory.
1199+
string blobName = BlobPrefix + Guid.NewGuid();
1200+
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
1201+
1202+
// For the purposes of the sample, check to see whether the blob exists.
1203+
Console.WriteLine("Blob {0} exists? {1}", blobName, await blob.ExistsAsync());
1204+
1205+
try
1206+
{
1207+
// Writing to the blob creates it on the service.
1208+
await blob.UploadTextAsync(string.Format("This is a blob named {0}", blobName));
1209+
}
1210+
catch (StorageException e)
1211+
{
1212+
Console.WriteLine(e.Message);
1213+
Console.ReadLine();
1214+
throw;
1215+
}
1216+
1217+
// Check again to see whether the blob exists.
1218+
Console.WriteLine("Blob {0} exists? {1}", blobName, await blob.ExistsAsync());
1219+
1220+
return blob;
1221+
}
1222+
1223+
/// <summary>
1224+
/// Gets a reference to a blob by making a request to the service.
1225+
/// </summary>
1226+
/// <param name="container">The container.</param>
1227+
/// <param name="blobName">The blob name.</param>
1228+
/// <returns>A Task object.</returns>
1229+
private static async Task GetExistingBlobReference(CloudBlobContainer container, string blobName)
1230+
{
1231+
try
1232+
{
1233+
// Get a reference to a blob with a request to the server.
1234+
// If the blob does not exist, this call will fail with a 404 (Not Found).
1235+
ICloudBlob blob = await container.GetBlobReferenceFromServerAsync(blobName);
1236+
1237+
// The previous call gets the blob's properties, so it's not necessary to call FetchAttributes
1238+
// to read a property.
1239+
Console.WriteLine("Blob {0} was last modified at {1} local time.", blobName,
1240+
blob.Properties.LastModified.Value.LocalDateTime);
1241+
}
1242+
catch (StorageException e)
1243+
{
1244+
if (e.RequestInformation.HttpStatusCode == 404)
1245+
{
1246+
Console.WriteLine("Blob {0} does not exist.", blobName);
1247+
Console.WriteLine("Additional error information: " + e.Message);
1248+
}
1249+
else
1250+
{
1251+
Console.WriteLine(e.Message);
1252+
Console.ReadLine();
1253+
throw;
1254+
}
1255+
}
1256+
1257+
Console.WriteLine();
1258+
}
1259+
11951260
/// <summary>
11961261
/// Creates the specified number of sequentially named block blobs, in a flat structure.
11971262
/// </summary>
@@ -1239,7 +1304,6 @@ private static async Task CreateSequentiallyNamedBlockBlobs(CloudBlobContainer c
12391304
}
12401305
}
12411306

1242-
12431307
/// <summary>
12441308
/// Creates the specified number of nested block blobs at a specified number of levels.
12451309
/// </summary>
@@ -1296,7 +1360,6 @@ private static async Task CreateNestedBlockBlobs(CloudBlobContainer container, s
12961360
}
12971361
}
12981362

1299-
13001363
/// <summary>
13011364
/// Gets a reference to a blob created previously, and copies it to a new blob in the same container.
13021365
/// </summary>
@@ -1465,7 +1528,7 @@ private static async Task UploadBlobInBlocks(CloudBlobContainer container)
14651528
rnd.NextBytes(randomBytes);
14661529

14671530
// Get a reference to a new block blob.
1468-
CloudBlockBlob blob = container.GetBlockBlobReference("sample-blob-" + Guid.NewGuid().ToString());
1531+
CloudBlockBlob blob = container.GetBlockBlobReference("sample-blob-" + Guid.NewGuid());
14691532

14701533
// Specify the block size as 256 KB.
14711534
int blockSize = 256 * 1024;
@@ -1551,7 +1614,6 @@ private static async Task UploadBlobInBlocks(CloudBlobContainer container)
15511614
}
15521615
}
15531616

1554-
15551617
/// <summary>
15561618
/// Reads the blob's block list, and indicates whether the blob has been committed.
15571619
/// </summary>
@@ -1581,7 +1643,6 @@ private static async Task ReadBlockList(CloudBlockBlob blob)
15811643
Console.WriteLine();
15821644
}
15831645

1584-
15851646
/// <summary>
15861647
/// Returns a URI containing a SAS for the blob.
15871648
/// </summary>
@@ -1604,7 +1665,8 @@ private static string GetBlobSasUri(CloudBlobContainer container, string blobNam
16041665
// to construct a shared access policy that is saved to the container's shared access policies.
16051666
SharedAccessBlobPolicy adHocSAS = new SharedAccessBlobPolicy()
16061667
{
1607-
// Omit SAS start time to avoid clock skew. Start time is assumed to be the time when the service receives the request.
1668+
// When the start time for the SAS is omitted, the start time is assumed to be the time when the storage service receives the request.
1669+
// Omitting the start time for a SAS that is effective immediately helps to avoid clock skew.
16081670
SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
16091671
Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Create
16101672
};
@@ -1629,7 +1691,6 @@ private static string GetBlobSasUri(CloudBlobContainer container, string blobNam
16291691
return blob.Uri + sasBlobToken;
16301692
}
16311693

1632-
16331694
/// <summary>
16341695
/// Tests a blob SAS to determine which operations it allows.
16351696
/// </summary>

0 commit comments

Comments
 (0)