@@ -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