Using Cloud Storage with .NET

This part of the .NET Bookshelf tutorial shows how to store images in Cloud Storage.

This page is part of a multi-page tutorial. To start from the beginning and read the setup instructions, go to .NET Bookshelf App.

Creating a Cloud Storage bucket

The following instructions show how to create a Cloud Storage bucket. Buckets are the basic containers that hold your data in Cloud Storage.

  1. In a terminal window, enter the following command:

    gsutil mb gs://[YOUR-BUCKET-NAME]

    Where:

    • [YOUR-BUCKET-NAME] represents the name of your Cloud Storage bucket.
  2. To view uploaded images in the bookshelf app, set the bucket's default access control list (ACL) to public-read.

    gsutil defacl set public-read gs://[YOUR-BUCKET-NAME]

Configuring settings

Running the app on your local machine

In Visual Studio, press F5 to run the project. Now you can browse the app's web pages to add, edit, and delete books with cover images.

Deploying the app to Compute Engine

  1. In Visual Studio, in the Solution Explorer pane, right-click 3-binary-data, and click Publish.

    Publish app

  2. Create a new custom profile as you did in the Using Structured Data part of this tutorial.

  3. Click Publish.

App structure

Binary data sample structure

The app uses Cloud Storage to store binary data, pictures in this case. It continues to use a structured database for the book information: Cloud Datastore, Cloud SQL, or SQL Server. The browser fetches images directly from Cloud Storage.

Understanding the code

This section walks you through the app's code and explains how it works.

Handling user uploads

The form has a new <input type="file"> tag so the user can upload a file.

<div class="form-group">
    @Html.Label("Cover Image")
    <input type="file" id="image" name="image" value="@Model.Book.ImageUrl" class="form-control">
    @Html.HiddenFor(model => model.Book.ImageUrl)
</div>

Uploading to Cloud Storage

The BooksController.Create() method now uploads the image.

// POST: Books/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Book book, HttpPostedFileBase image)
{
    if (ModelState.IsValid)
    {
        _store.Create(book);
        // If book cover image submitted, save image to Cloud Storage
        if (image != null)
        {
            var imageUrl = await _imageUploader.UploadImage(image, book.Id);
            book.ImageUrl = imageUrl;
            _store.Update(book);
        }
        return RedirectToAction("Details", new { id = book.Id });
    }
    return ViewForm("Create", "Create", book);
}

The ImageUploader class invokes the Google.Apis.Storage.v1.ClientWrapper.StorageClient API to upload the image.

_storageClient = StorageClient.Create();
        public async Task<String> UploadImage(HttpPostedFileBase image, long id)
        {
            var imageAcl = PredefinedObjectAcl.PublicRead;

            var imageObject = await _storageClient.UploadObjectAsync(
                bucket: _bucketName,
                objectName: id.ToString(),
                contentType: image.ContentType,
                source: image.InputStream,
                options: new UploadObjectOptions { PredefinedAcl = imageAcl }
            );

            return imageObject.MediaLink;
        }

Serving images from Cloud Storage

Because the app has the public URL for the image, serving the image is straightforward. Serving directly from Cloud Storage is helpful, because the requests leverage Google’s global serving infrastructure, and the app doesn’t have to respond to requests for images. This frees up CPU cycles for other requests.

<img class="book-image"
     src="@(String.IsNullOrEmpty(Model.ImageUrl) ?
"http://placekitten.com/g/128/192" : Model.ImageUrl)">
Was this page helpful? Let us know how we did:

Send feedback about...