Take Photographs From Windows 8 Apps/Auto Upload Them to the Cloud–Pt. 3/6
Creating a web service






Published at DZone with permission of Bruno Terkaly, author and DZone MVB. (source)- We are ready to turn our attention to the web service that will allow us to upload the photo to the cloud
- 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.
- As you recall, the Shared Access Signature is needed so that the Windows 8 application can upload the photo directly to the cloud.
- This bypasses the need to go through a web site (web role).
- We can save money and gain scale.
- We will start with the server-side/web services project.
- We will leverage the ASP.NET Web API, built into Visual Studio 2012.
- 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).
- 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.
- 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.
- Select ASP.NET MVC 4 Web Role
- Click the > button to move the ASP.NET MVC 4 Web Role to the right pane
- Click OK
- Select Web API for a project template
- Click OK
- 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.
- 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.
- Your RouteConfig.cs file should look like this.
- Note that the following route is being added:
- api/{controller}/{container}/{blobname}
- Note that the following route is being added:
Figure 10 : MainWindow.xaml.cs
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
![]()
- 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.
- This is where we will add some of our code to return the Shared Access Signature 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, automatically in JSON format.
- We will return a Shared Access Signature in JSON format.
- Note that the methods above - Get(), Post(), Put(), Delete() - map to specific CRUD operations and HTTP verbs executed by the Windows 8 application.
- 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.
- As you recall from the previous section, we modified the routing structures to support the passing of parameters.
- This means we need to add a third Get() method to ValuesController.cs.
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)
{
}
}- 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
- This method will be called when the client issues the following web request:
- You can see that the parameters embedded directly into the URL.
- The Web API framework will parse the parameters and map them to the parameters seen above (container, blobname)
- 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 Microsoft.WindowsAzure; using Microsoft.WindowsAzure.StorageClient;
The final class is presented below.
![]()
- 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.
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)
{
}
}
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





