Skip to content

Commit d24bd4b

Browse files
committed
fix canonicalized resource example
1 parent b06c7e2 commit d24bd4b

File tree

1 file changed

+30
-31
lines changed

1 file changed

+30
-31
lines changed

articles/storage/common/storage-rest-api-auth.md

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,17 @@ ms.subservice: common
1616

1717
This article shows you how to use the Blob Storage Service REST APIs and how to authorize the call to the service. It's written from the point of view of a developer who knows nothing about REST and no idea how to make a REST call. We look at the reference documentation for a REST call and see how to translate it into an actual REST call – which fields go where? After learning how to set up a REST call, you can leverage this knowledge to use any of the other Storage Service REST APIs.
1818

19-
## Prerequisites
19+
## Prerequisites
2020

2121
The application lists the containers in blob storage for a storage account. To try out the code in this article, you need the following items:
2222

23-
* Install [Visual Studio 2019](https://www.visualstudio.com/visual-studio-homepage-vs.aspx) with the following workload:
24-
- Azure development
23+
- Install [Visual Studio 2019](https://www.visualstudio.com/visual-studio-homepage-vs.aspx) with the **Azure development** workload.
2524

26-
* An Azure subscription. If you don't have an Azure subscription, create a [free account](https://azure.microsoft.com/free/?WT.mc_id=A261C142F) before you begin.
25+
- An Azure subscription. If you don't have an Azure subscription, create a [free account](https://azure.microsoft.com/free/?WT.mc_id=A261C142F) before you begin.
2726

28-
* A general-purpose storage account. If you don't yet have a storage account, see [Create a storage account](storage-quickstart-create-account.md).
27+
- A general-purpose storage account. If you don't yet have a storage account, see [Create a storage account](storage-quickstart-create-account.md).
2928

30-
* The example in this article shows how to list the containers in a storage account. To see output, add some containers to blob storage in the storage account before you start.
29+
- The example in this article shows how to list the containers in a storage account. To see output, add some containers to blob storage in the storage account before you start.
3130

3231
## Download the sample application
3332

@@ -61,11 +60,11 @@ Let's look at the page in the REST API Reference for the [ListContainers](/rest/
6160

6261
**Request Method**: GET. This verb is the HTTP method you specify as a property of the request object. Other values for this verb include HEAD, PUT, and DELETE, depending on the API you are calling.
6362

64-
**Request URI**: https://myaccount.blob.core.windows.net/?comp=list  This is created from the blob storage account endpoint `http://myaccount.blob.core.windows.net` and the resource string `/?comp=list`.
63+
**Request URI**: `https://myaccount.blob.core.windows.net/?comp=list`.  This is created from the blob storage account endpoint `http://myaccount.blob.core.windows.net` and the resource string `/?comp=list`.
6564

6665
[URI parameters](/rest/api/storageservices/List-Containers2#uri-parameters): There are additional query parameters you can use when calling ListContainers. A couple of these parameters are *timeout* for the call (in seconds) and *prefix*, which is used for filtering.
6766

68-
Another helpful parameter is *maxresults:* if more containers are available than this value, the response body will contain a *NextMarker* element that indicates the next container to return on the next request. To use this feature, you provide the *NextMarker* value as the *marker* parameter in the URI when you make the next request. When using this feature, it is analogous to paging through the results.
67+
Another helpful parameter is *maxresults:* if more containers are available than this value, the response body will contain a *NextMarker* element that indicates the next container to return on the next request. To use this feature, you provide the *NextMarker* value as the *marker* parameter in the URI when you make the next request. When using this feature, it is analogous to paging through the results.
6968

7069
To use additional parameters, append them to the resource string with the value, like this example:
7170

@@ -96,17 +95,17 @@ In our sample project, the code for creating the Authorization header is in a se
9695

9796
To build the request, which is an HttpRequestMessage object, go to ListContainersAsyncREST in Program.cs. The steps for building the request are:
9897

99-
* Create the URI to be used for calling the service.
100-
* Create the HttpRequestMessage object and set the payload. The payload is null for ListContainersAsyncREST because we're not passing anything in.
101-
* Add the request headers for x-ms-date and x-ms-version.
102-
* Get the authorization header and add it.
98+
- Create the URI to be used for calling the service.
99+
- Create the HttpRequestMessage object and set the payload. The payload is null for ListContainersAsyncREST because we're not passing anything in.
100+
- Add the request headers for x-ms-date and x-ms-version.
101+
- Get the authorization header and add it.
103102

104103
Some basic information you need:
105104

106-
* For ListContainers, the **method** is `GET`. This value is set when instantiating the request.
107-
* The **resource** is the query portion of the URI that indicates which API is being called, so the value is `/?comp=list`. As noted earlier, the resource is on the reference documentation page that shows the information about the [ListContainers API](/rest/api/storageservices/List-Containers2).
108-
* The URI is constructed by creating the Blob service endpoint for that storage account and concatenating the resource. The value for **request URI** ends up being `http://contosorest.blob.core.windows.net/?comp=list`.
109-
* For ListContainers, **requestBody** is null and there are no extra **headers**.
105+
- For ListContainers, the **method** is `GET`. This value is set when instantiating the request.
106+
- The **resource** is the query portion of the URI that indicates which API is being called, so the value is `/?comp=list`. As noted earlier, the resource is on the reference documentation page that shows the information about the [ListContainers API](/rest/api/storageservices/List-Containers2).
107+
- The URI is constructed by creating the Blob service endpoint for that storage account and concatenating the resource. The value for **request URI** ends up being `http://contosorest.blob.core.windows.net/?comp=list`.
108+
- For ListContainers, **requestBody** is null and there are no extra **headers**.
110109

111110
Different APIs may have other parameters to pass in such as *ifMatch*. An example of where you might use ifMatch is when calling PutBlob. In that case, you set ifMatch to an eTag, and it only updates the blob if the eTag you provide matches the current eTag on the blob. If someone else has updated the blob since retrieving the eTag, their change won't be overridden.
112111

@@ -307,7 +306,7 @@ What are CanonicalizedHeaders and CanonicalizedResource? Good question. In fact,
307306

308307
Let's start with those two canonicalized fields, because they are required to create the Authorization header.
309308

310-
**Canonicalized Headers**
309+
### Canonicalized headers
311310

312311
To create this value, retrieve the headers that start with "x-ms-" and sort them, then format them into a string of `[key:value\n]` instances, concatenated into one string. For this example, the canonicalized headers look like this:
313312

@@ -352,7 +351,7 @@ private static string GetCanonicalizedHeaders(HttpRequestMessage httpRequestMess
352351
}
353352
```
354353

355-
**Canonicalized Resource**
354+
### Canonicalized resource
356355

357356
This part of the signature string represents the storage account targeted by the request. Remember that the Request URI is
358357
`<http://contosorest.blob.core.windows.net/?comp=list>`, with the actual account name (`contosorest` in this case). In this example, this is returned:
@@ -376,10 +375,10 @@ private static string GetCanonicalizedResource(Uri address, string storageAccoun
376375

377376
foreach (var item in values.AllKeys.OrderBy(k => k))
378377
{
379-
sb.Append('\n').Append(item).Append(':').Append(values[item]);
378+
sb.Append('\n').Append(item.ToLower()).Append(':').Append(values[item]);
380379
}
381380

382-
return sb.ToString().ToLower();
381+
return sb.ToString();
383382
}
384383
```
385384

@@ -433,9 +432,9 @@ The AuthorizationHeader is the last header placed in the request headers before
433432

434433
That covers everything you need to know to put together a class with which you can create a request to call the Storage Services REST APIs.
435434

436-
## How about another example?
435+
## Example: List blobs
437436

438-
Let's look at how to change the code to call ListBlobs for container *container-1*. This code is almost identical to the code for listing containers, the only differences being the URI and how you parse the response.
437+
Let's look at how to change the code to call the List Blobs operation for container *container-1*. This code is almost identical to the code for listing containers, the only differences being the URI and how you parse the response.
439438

440439
If you look at the reference documentation for [ListBlobs](/rest/api/storageservices/List-Blobs), you find that the method is *GET* and the RequestURI is:
441440

@@ -463,26 +462,26 @@ foreach (XElement container in x.Element("Blobs").Elements("Blob"))
463462

464463
When you run this sample, you get results like the following:
465464

466-
**Canonicalized Headers:**
465+
**Canonicalized headers:**
467466

468467
```
469468
x-ms-date:Fri, 17 Nov 2017 05:16:48 GMT\nx-ms-version:2017-07-29\n
470469
```
471470

472-
**Canonicalized Resource:**
471+
**Canonicalized resource:**
473472

474473
```
475474
/contosorest/container-1\ncomp:list\nrestype:container
476475
```
477476

478-
**MessageSignature:**
477+
**Message signature:**
479478

480479
```
481480
GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 17 Nov 2017 05:16:48 GMT
482481
\nx-ms-version:2017-07-29\n/contosorest/container-1\ncomp:list\nrestype:container
483482
```
484483

485-
**AuthorizationHeader:**
484+
**Authorization header:**
486485

487486
```
488487
SharedKey contosorest:uzvWZN1WUIv2LYC6e3En10/7EIQJ5X9KtFQqrZkxi6s=
@@ -522,7 +521,7 @@ Content-Length: 1135
522521

523522
```xml
524523
<?xml version="1.0" encoding="utf-8"?>
525-
<EnumerationResults
524+
<EnumerationResults
526525
ServiceEndpoint="http://contosorest.blob.core.windows.net/" ContainerName="container-1">
527526
<Blobs>
528527
<Blob>
@@ -571,7 +570,7 @@ In this article, you learned how to make a request to the blob storage REST API.
571570

572571
## Next steps
573572

574-
* [Blob Service REST API](/rest/api/storageservices/blob-service-rest-api)
575-
* [File Service REST API](/rest/api/storageservices/file-service-rest-api)
576-
* [Queue Service REST API](/rest/api/storageservices/queue-service-rest-api)
577-
* [Table Service REST API](/rest/api/storageservices/table-service-rest-api)
573+
- [Blob Service REST API](/rest/api/storageservices/blob-service-rest-api)
574+
- [File Service REST API](/rest/api/storageservices/file-service-rest-api)
575+
- [Queue Service REST API](/rest/api/storageservices/queue-service-rest-api)
576+
- [Table Service REST API](/rest/api/storageservices/table-service-rest-api)

0 commit comments

Comments
 (0)