How To Take Photographs From Windows 8 Applications And Automatically Upload Them To The Cloud -- Part 1 http://blogs.msdn.com/b/brunoterkaly/archive/2012/08/25/how-to-take-photographs-from-windows-8-applications-and-automatically-upload-them-to-the-cloud-part-1-of-6.aspx
How To Take Photographs From Windows 8 Applications And Automatically Upload Them To The Cloud -- Part 2 http://blogs.msdn.com/b/brunoterkaly/archive/2012/08/26/tet3.aspx
How To Take Photographs From Windows 8 Applications And Automatically Upload Them To The Cloud -- Part 3 http://blogs.msdn.com/b/brunoterkaly/archive/2012/08/27/test23.aspx
How To Take Photographs From Windows 8 Applications And Automatically Upload Them To The Cloud -- Part 4 http://blogs.msdn.com/b/brunoterkaly/archive/2012/08/28/how-to-take-photographs-from-windows-8-applications-and-automatically-upload-them-to-the-cloud-part-4-of-6.aspx
How To Take Photographs From Windows 8 Applications And Automatically Upload Them To The Cloud -- Part 5 http://blogs.msdn.com/b/brunoterkaly/archive/2012/08/29/step-5-of-6.aspx
How To Take Photographs From Windows 8 Applications And Automatically Upload Them To The Cloud -- Part 6 http://blogs.msdn.com/b/brunoterkaly/archive/2012/08/29/how-to-take-photographs-from-windows-8-applications-and-automatically-upload-them-to-the-cloud-part-6-of-6.aspx
Creating a web service
001
  1. We are ready to turn our attention to the web service that will allow us to upload the photo to the cloud
  2. We will need to return to the Windows 8 project later, once we have completed the cloud project which will provide the Shared Access Signature.
  3. As you recall, the Shared Access Signature is needed so that the Windows 8 application can upload the photo directly to the cloud.
    1. This bypasses the need to go through a web site (web role).
    2. We can save money and gain scale.
  4. We will start with the server-side/web services project.
  5. We will leverage the ASP.NET Web API, built into Visual Studio 2012.
  6. The Web API is a framework for building and consuming HTTP services that can reach a broad range of clients including browsers, phones and tablets.
    • You can typically choose either of these two project types: (1) Windows Communication Foundation (WCF) ; or (2) ASP.NET Web API, which is included with MVC version 4.
    • We will take the newer, more modern concepts that ASP.NET Web API brings to the table, truly embracing HTTP concepts (URIs and verbs).
  7. Also, the ASP.NET Web API can be used to create services that use more advanced HTTP features with greater ease  - such as request/response headers, hypermedia constructs.

Building the Web Service
002
  1. Let's begin by starting Visual Studio 2012 as Administrator. Here are the steps to create the server-side web service, using the ASP.NET MVC 4 Web API:
    • Click on the File menu and choose New/Project.
    • Make sure the framework selected is .NET Framework 4
    • Choose Cloud from installed templates
    • Choose Windows Azure Cloud Service
    • Enter a Name of WebService and Location of your choice.
    • Click OK.

Choosing the correct web role
003
  1. Select ASP.NET MVC 4 Web Role
  2. Click the > button to move the ASP.NET MVC 4 Web Role to the right pane
  3. Click OK

Choosing Web API
004
  1. Select Web API for a project template
  2. Click OK

A variety of files will be generated by Visual Studio. This can be overwhelming but we only need to worry about a couple of files.
005
  1. RouteConfig.cs is used to map the URLs.
    • The url portion of the route is simply a matching mechanism for the request.
    • If the url matches a particular route, the framework binds the request to a specific controller and action method to handle the request.
    • In short, the routing mechanism maps incoming URLs to the application, so that the right Controller and Action method executes to process them.
  2. ValuesController.cs is where we define the action methods that will handle the request, as expressed by the URL and verb used in the web request.
    • VisualController.cs is an important file, because it contains the code that will execute when the Windows 8 client submits an HTTP request against the web service.
    • This is where we will add some of our code to return the JSON data required by the Windows 8 application.
    • The ValuesController class is generated by Visual Studio, and it inherits from ApiController, which returns data that is serialized and sent to the client.

RouteConfig.cs
006
  1. Your RouteConfig.cs file should look like this.
    • Note that the following route is being added:
      • api/{controller}/{container}/{blobname}

  MainWindow.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        // Add a route to support the passing of a container name
        // and the blob name, which is the picture uploaded from the
        // Windows 8 application. The URL below (issued by a Windows 8 Application)
        // resolves to call an action method in ValuesController.cs
        routes.MapHttpRoute(
            name: "DefaultApi2",
            routeTemplate: "api/{controller}/{container}/{blobname}"
        );
 
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}


Modifiying the ValuesController.cs
007
  1. Once again, VisualController.cs is an important file, because it contains the code that will execute when the Windows 8 client submits an HTTP request against the web service.
  2. This is where we will add some of our code to return the Shared Access Signature required by the Windows 8 application.
  3. The ValuesController class is generated by Visual Studio, and it inherits from ApiController, which returns data that is serialized and sent to the client, automatically in JSON format.
    • We will return a Shared Access Signature in JSON format.
  4. Note that the methods above - Get(), Post(), Put(), Delete() - map to specific CRUD operations and HTTP verbs executed by the Windows 8 application.
  5. This is the beauty of the ASP.NET Web API framework: it automatically routes the HTTP verbs used by the client directly to the methods defined in the VisualController class, minimizing potential programming mistakes.
  6. As you recall from the previous section, we modified the routing structures to support the passing of parameters.
  7. This means we need to add a third Get() method to ValuesController.cs.

  ValuesController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
 
    // GET api/values/5
    public string Get(int id)
    {
        return "value";
    }
 
    // POST api/values
    public void Post(string value)
    {
    }
 
    // PUT api/values/5
    public void Put(int id, string value)
    {
    }
 
    // DELETE api/values/5
    public void Delete(int id)
    {
    }
}


Adding a new method
008
  1. Note that in the figure above we will add an additional method to support the passing of 2 parameters from the Windows 8 Application.
    • This method will be called when the client issues the following web request:
      • http://127.0.0.1:81/api/values?container=photocontainer&blobname=photo1.jpg
  2. You can see that the parameters embedded directly into the URL.
  3. The Web API framework will parse the parameters and map them to the parameters seen above (container, blobname)
  4. At the top of the ValuesController.cs file, you will need to add 2 using statements, as seen below:
    • The using statements are needed because the code we are about to add leverages the assemblies in the Azure SDK.

 using statements
1
2
3
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;


The final class is presented below.
009
  1. Some noteworthy points include:
    • A storage account is needed. We get this by signing up to a free 90-day account with Azure. See end of this post.
    • We can leverage the built in storage emulator which allows us to emulate cloud storage on our local system.
      • But I want to show you how to deploy to a real data center
    • In a future post we will make some trivial changes and deploy the Web Service to a Microsoft Data Center.
    • Blobs are stored in containers.
      • They are not stand alone.
    • The Windows 8 Application passes in the container name, in addition to the photo name.
    • The container is designated to be public, allowing any application with the photograph URL to download it.
    • The main point of our Get() method is to return a Shared Access Signature.
    • Creating a Shared Access Signature requires you to specify the permission level and the expiration time.
    • You can think of a Shared Access Signature as a hall pass in a high school, allowing you to walk the hallways for a specified period of time.
      • Once your hall pass expires you lose the right to walk the hallway.
      • When the SAS expires you can no longer add/modify blobs (photos)
    • Ultimately, the Get() method returns the Shared Access Signature to the Windows 8 application.
      • The Shared Access Signature gives the Windows 8 application has 4 hours to write photos to the specified container.

 ValuesController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
    // GET api/values/container/blobname
    public string Get(string container, string blobname)
    {
        try
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("DataConnectionString"));

            //CloudStorageAccount storageAccount = CloudStorageAccount.DevelopmentStorageAccount;

            // Client object provides a client for accessing the Windows Azure Blob service.
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // All blobs are written into a container
            CloudBlobContainer blobContainer = blobClient.GetContainerReference(container);

            // Create container if does not exist.
            blobContainer.CreateIfNotExist();

            // Mark the container of the image as public so that can be read by anyone.
            BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
            containerPermissions.PublicAccess = BlobContainerPublicAccessType.Blob;

            // Define a 4 hour window that the Windows 8 client can write to Azure Blob Storage.
            containerPermissions.SharedAccessPolicies.Add("mypolicy", new SharedAccessPolicy()
            {
                Permissions = SharedAccessPermissions.Write, // | SharedAccessPermissions.Read ,
                //To be available immediately don't set SharedAccessStartTime =
                SharedAccessExpiryTime = DateTime.Now.Add(TimeSpan.FromHours(4))
            });

            // Set the permissions so that Windows 8 client can write to the container
            // for the 4 hours specified above.
            blobContainer.SetPermissions(containerPermissions);

            // Create the shared access signature that will be added to the URL.
            string sas = blobContainer.GetSharedAccessSignature(new SharedAccessPolicy(), "mypolicy");

            // Creat the URI to be return to the Windows 8 client that will be used to write
            // to blob storage.
            return string.Format("{0}/{1}{2}", blobContainer.Uri, blobname, sas);

        }
        catch (Exception ex)
        {
            // Return error message to client.
            string error = ex.Message;
            return error;
        }

    }
    // GET api/values/5
    public string Get(int id)
    {
        return "value";
    }

    // POST api/values
    public void Post(string value)
    {
    }

    // PUT api/values/5
    public void Put(int id, string value)
    {
    }

    // DELETE api/values/5
    public void Delete(int id)
    {
    }
}

Future Posts
010
  1. Some interesting posts still remain
    • We still need to add the data connection string that will let the web service grant SASs to Windows 8 clients
      • The current web service is not fully functional yet.
      • That is the next post
    • Next post:
      • Add connection strings
      • Deploying and
      • Testing the Web Service
    • Adjusting the Windows 8 Client app to talk to our hosted service
  2. Now is the time to download the free trial

Thanks..
I appreciate that you took the time to read this post. I look forward to your comments.