Before we start writing some code against the containers, we should probably discuss where this type of functionality is useful.
If you just need a shared
storage area where you can read BLOBs, you’ll probably eventually use
the Azure Drive functionality rather than interacting with the BLOB storage APIs directly. Even so,
it’s still useful to understand how the BLOB storage APIs work, because
Azure Drive interacts with these APIs too.
If you need a
scalable application in which more than one role needs to write to a
single shared storage area, then you’ll need to use the StorageClient
library or the REST APIs directly.
Over the next few sections,
we’ll be looking at the kinds of operations you can perform against
containers. Using containers is particularly interesting when you need
to dynamically create storage areas and assign permissions to different
parties in a scalable fashion.
Typical scenarios for using containers are file hosting, enterprise
workflows, and data manipulation applications that need to access data.
In the next chapter, we’ll look at how you can use containers in these
kinds of scenarios by generating dynamic keys; we’ll also talk about
setting permissions on containers.
For now, we’ll return to our
podcast example. You need a method of creating public and private
containers to store your original and converted podcasts in. In this
sample application, you’ll create an ASP.NET web form page in which to
do that. Your final application will look like the screenshot displayed
in figure 1.
Over the next few sections we’ll look at the following topics, which will help you build the web page displayed in figure 1:
By the end of this section, you’ll have created the above web page and you’ll have a vast knowledge of containers.
Before we get started, you need to create a new web role project in Visual Studio . You should call this web role PodcastSample.
1. Accessing the StorageClient library
There are two ways of
interacting with any of the storage services: you can either use the
REST API directly or you can use the StorageClient library API.
One of the reasons that we’ll
look at both methods is that the StorageClient library is just a .NET
wrapper for the REST API. For new features, Microsoft will often release
the REST API call before adding the feature to the StorageClient
library. By understanding both methods of interaction, you’ll be able to
use any new feature immediately (if you need to).
Another
reason for looking at the REST API is that the underlying mechanism is
heavily abstracted away from you. By understanding the underlying calls,
you can make the best decisions architecturally for your application
(especially regarding performance).
Now you might be thinking, “If
the REST API is so great, why are we using the StorageClient library?”
The answer to that is quite simple: as flexible as the REST API is to
use, it’s one huge pain. Using the REST API directly means we get to
write unreadable code; HttpWebRequest
code with no IntelliSense support. By using the StorageClient library
wherever possible, we get to write familiar .NET code (with IntelliSense
support), which increases productivity. We can ultimately spend more
time doing more important things (like browsing the internet or playing
Halo).
Although the StorageClient
library (Microsoft.WindowsAzure.StorageClient.dll) is automatically
referenced in any new web or worker role projects that you create, you
can add the reference manually if you need to. You can find the
reference at C:\Program Files\Windows Azure SDK\v1.1\ref\.
You don’t need to add
this assembly to your project; it’s already referenced. But when you’re
building your own code, you’ll probably want to split your code into
proper layers. If you do that, you’ll need to add the assembly to your
own custom assembly.
Now that you know how to
reference your assembly, let’s look at how you configure the
StorageClient library to access your development storage account.
2. Accessing development storage
To use development storage for
storing BLOBs, you need to configure your application to use the
development BLOB service in the same way as you would if it were the
live system.
There are two ways to tell your
code to connect to the local development storage. The first is to use a
magic string as your connection string. If you set your connection
string to UseDevelopmentStorage=true,
the development storage fabric will respond to the connections. You can
also put in the real development storage fabric connection. The format
of the connection string for development storage will look a lot like a
production connection string. The following parts are all that’s
different:
Account name— The only account name that’s supported for development storage is the default name, devstoreaccount1.
Account shared key— The default name for this value is this: Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50u SRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==
Endpoint—
The BLOB storage endpoint for development storage BLOB services is by
default 127.0.0.1:10000. To access the BLOB file in the example in this section from the development storage BLOB service, you would use the following URI: http://127.0.0.1:10000/devstoreaccount1/ChrisConverted/Podcast01.wma. This URI can be formalized as http://127.0.0.1:10000/<StorageAccountName>/<Container>/<BlobName>.
You
can change the default values for each of these items in the
DSService.exe.config file, but it’s recommended that you use the default
values.
In development storage,
there’s no ability to create or host multiple storage accounts and
there’s no Azure portal, so you can’t easily generate a new key. The
endpoints and URI structure also differ from the live system.
With that knowledge in hand, let’s look at how you can use this information to access your account in code.
Storing Account Details in the Service Configuration File
To make things a little easier, the Windows Azure SDK provides a property that will spin up a CloudStorageAccount object with the default development storage settings:
CloudStorageAccount = CloudStorageAccount.DevelopmentStorageAccount;
Although this is probably
the quickest method of getting started, it isn’t best practice. Starting
this way, you’re effectively hardcoding your application to your
development account. You’d have to modify and recompile your code before
you could deploy your application to the live system, which can
complicate your build process and introduce bugs.
The best practice for
storing this information is to store the data in the service
configuration file, which gives you the option to change this
information without redeploying the whole application. For example, if
your shared key is compromised, then you would be able to generate a new
shared key and modify your application to use the new key by simply
changing the service configuration via the Azure portal.
To help you easily use the
ServiceConfiguration.cscfg file to store your account details, the
StorageClient library provides a method that can extract the account
name, shared key, and endpoint from a configuration setting. The
following call is used by the library to extract these values:
CloudStorageAccount =
CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
In the above example, your account details will be extracted from a configuration setting named DataConnectionString.
Although this code is
specific to the StorageClient library, you should still store the
account details in the service configuration file, even if you’re using
the REST API directly. Storing the details there will simplify and
standardize your code and allow you to easily use both the StorageClient
library and the REST API directly within your application (you don’t
want to have to modify two different settings to access your account).
Now that you know how easy it
is to extract an account from your configuration, let’s look at how you
define that configuration setting.
Defining Configuration Settings
You’ll first need to define your configuration settings in the service
definition file before you can configure them. The following setting is
the standard method of defining your storage account in your service
definition file.
<ConfigurationSettings>
<Setting name="DataConnectionString"/>
</ConfigurationSettings>
Notice in this code that DataConnectionString is the same name that was passed to the FromConfigurationSetting method to extract the account name, shared key, and endpoint values.
Communicating with Development Storage
After you’ve defined the
configuration settings, you can set the runtime values in your service
configuration file. The following configuration settings are the
defaults used to talk to development storage:
<ConfigurationSettings>
<Setting name="DataConnectionString"
value="UseDevelopmentStorage=true" />
</ConfigurationSettings>
By setting the value of DataConnectionString to UseDevelopmentStorage=true,
you’re effectively telling the storage client to extract your settings
from the DSService.exe.config file, which gives you the same result as
using the DevelopmentStorageAccount property.
The advantage of using the FromConfigurationSetting method over the DevelopmentStorageAccount
property is that you can modify the service configuration file to use
the live account details (shown later in this chapter) without having to
recompile or redeploy your application.
Now that your
application is configured to use development storage via the
StorageClient library, you can continue on and create your web page.