Plan
- Part 1 : Introduction
- Part 2 : Sample CRUD application using Azure tables
- Part 3 : Sample web application using Azure Blobs and Queue
- Part 4 : SQL Azure database
- Part 5 : Deploying your application as PAAS
Introduction
In this chapter, we will explain step by step the creation of an Asp.Net web application that works with Azure table services.Using the code
Prerequisite :
in this section we will define only useful classes and methods that we will used to create our sample application .0) CloudStorageAccount class :
represents a windows azure storage account.Methods :
- Parse(
String
connection_string) : parse a connection string and create a CloudStorageAccount object from connection string parameter. CloudTableClient
CreateCloudTableClient() : create a Table service client that allow us to create a table in Azure storage.
1) CloudTableClient class :
Methods :- GetTableReferencet(
string
table_name ) : get a reference to specified table identified by table_name parameter.
2) CloudTable class :
Represents a windows Azure table.Methods :
boolean
CreateIfNotExists() : create table if not exists in the storage and return true if table is recently created, else it will return false.- Execute(
TableOperation) :
execute a specific query on a table.
3) TableOperation class :
Methods :- InsertOrReplace(
TableEntity table_entity
) : this method can execute two operations : updating if given entity exists in the table entities, insertion if given tableEntity doesn't exists in table entities.
For more documentation about Azure classes and methods you can visit the following link : Azure Table Documentation
Coding :
0) Environment setup :Before you start coding, you need to download windows azure storage. In my case i used Nuget Package Manager :
check your project references :
1) Create a Server side
Models :PersonEntity class :
TableEntity
, is used to create a new entity. using Microsoft.WindowsAzure.Storage.Table;
namespace DataTableStorage1Sample.Model
{
public class PersonEntity : TableEntity
{
// Your entity type must expose a parameter-less constructor
public PersonEntity() { }
// Define the PK and RK
public PersonEntity(string PartitionKey, string RowKey)
{
this.PartitionKey = PartitionKey;
this.RowKey = RowKey;
}
public string firstName { get; set; }
public string lastName { get; set; }
}
}
AzureTableManager class :
- Get a reference of Azure storage Account (in our case we used the local storage),
- Create or get a reference of Azure table by Name.
- Create, update, delete and retrieve entities from an given Azure table.
using System;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using System.Collections.Generic;
using DataTableStorage1Sample.Model;
using System.Configuration;
namespace WebApplicationTables.Models
{
public class AzureTableManager
{
internal const string TableName = "Person";
private static CloudStorageAccount CreateStorageAccountFromConnectionString(string storageConnectionString)
{
CloudStorageAccount storageAccount;
try
{
//get a reference for our Azure storage account
storageAccount = CloudStorageAccount.Parse(storageConnectionString);
}
catch (FormatException)
{
Console.WriteLine("Invalid storage account information provided. Please confirm the AccountName and AccountKey are valid in the app.config file - then restart the application.");
throw;
}
catch (ArgumentException)
{
Console.WriteLine("Invalid storage account information provided. Please confirm the AccountName and AccountKey are valid in the app.config file - then restart the sample.");
Console.ReadLine();
throw;
}
return storageAccount;
}
public static CloudTable CreateTable()
{
// Retrieve storage account information from connection string.
CloudStorageAccount storageAccount = CreateStorageAccountFromConnectionString(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ToString());
// Create a table client for interacting with the table service
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
// Create a table client for interacting with the table service
CloudTable table = tableClient.GetTableReference(TableName);
try
{
if (table.CreateIfNotExists())
{
Console.WriteLine("Created Table named: {0}", TableName);
}
else
{
Console.WriteLine("Table {0} already exists", TableName);
}
}
catch (StorageException)
{
return null;
}
return table;
}
public static Boolean InsertEntity(CloudTable table, PersonEntity entity)
{
//i used insertorreplace method for updating and insertion operation
TableOperation insertOrMergeOperation = TableOperation.InsertOrReplace(entity);
// Execute the operation.
TableResult result = table.Execute(insertOrMergeOperation);
PersonEntity insertedCustomer = result.Result as PersonEntity;
//check if the operation is well processed
if (insertedCustomer == null)
{
return false;
}
return true;
}
public static List<PersonEntity> RetreiveAllEntries(CloudTable table)
{
//find all available entities from given Azure table
var entities = table.ExecuteQuery(new TableQuery<PersonEntity>()).ToList();
return entities;
}
public static Boolean DeleteEntity(CloudTable table, string partitionKey, string rowKey)
{
//create our delete operation
TableOperation retrieveOperation = TableOperation.Retrieve<PersonEntity>(partitionKey, rowKey);
//execute the query
TableResult result = table.Execute(retrieveOperation);
PersonEntity personEntity = result.Result as PersonEntity;
//check if the operation is well processed
if (personEntity == null)
{
return false;
}
//delete an existing entity
TableOperation deleteOperation = TableOperation.Delete(personEntity);
table.Execute(deleteOperation);
return true;
}
}
}
Controllers :
RestAzureTableMethodsController class :
ApiController
, that implement Restful services that permit to :- add a new entity to Azure table,
- modify some attributes of an existing entity in Azure table,
- delete an existing entity from Azure table,
- retrieve all entities from an existing Azure table.
using DataTableStorage1Sample.Model;
using Microsoft.WindowsAzure.Storage.Table;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Script.Serialization;
using WebApplicationTables.Models;
namespace WebApplicationTables.Controllers
{
public class RestAzureTableMethodsController : ApiController
{
[HttpGet]
public HttpResponseMessage insertEntity()
{
//get reference of current request
var request = HttpContext.Current.Request;
var status = false;
try{
//get parameters : obj is json object
var obj = request.Params["obj"];
//create a new entity from given parameter
PersonEntity personEntity = JsonConvert.DeserializeObject<PersonEntity>(obj);
//generate keys
//specify partition key
string partitionKey = "partitionKey1";
//create a unique key
string rowKey = DateTime.Now.ToString("ddMMyyyyHmmss");
CloudTable table = AzureTableManager.CreateTable();
personEntity.PartitionKey = partitionKey;
personEntity.RowKey = rowKey;
status = AzureTableManager.InsertEntity(table, personEntity);
}
catch
{
;
}
if (status == true)
{
return (new HttpResponseMessage(HttpStatusCode.OK));
}
else
{
return (new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
[HttpGet]
public HttpResponseMessage updateEntity()
{
//get reference of current request
var request = HttpContext.Current.Request;
var status = false;
try
{
//get parameters : obj is json object
var obj = request.Params["obj"];
PersonEntity personEntity = JsonConvert.DeserializeObject<PersonEntity>(obj);
CloudTable table = AzureTableManager.CreateTable();
status = AzureTableManager.InsertEntity(table, personEntity);
}
catch (Exception e)
{
;
}
if (status == true)
{
return (new HttpResponseMessage(HttpStatusCode.OK));
}
else
{
return (new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
[HttpGet]
public HttpResponseMessage deleteEntity()
{
//get reference of current request
var request = HttpContext.Current.Request;
var status = false;
try
{
//get parameters : we need only entity identifier
string partitionKey = request.Params["PartitionKey"];
string rowKey = request.Params["RowKey"];
CloudTable table = AzureTableManager.CreateTable();
status = AzureTableManager.DeleteEntity(table, partitionKey, rowKey);
}catch(Exception e){
status = false;
}
if (status == true)
{
return (new HttpResponseMessage(HttpStatusCode.OK));
}
else
{
return (new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
[HttpGet]
public IEnumerable<PersonEntity> retreiveEntities()
{
CloudTable table = AzureTableManager.CreateTable();
//return all available entities
return AzureTableManager.RetreiveAllEntries(table);
}
}
}
2) Create a Client side
In client side, we used AngularJs framework .JavaScript Code :
<script>
var app = angular.module('myApp', []);
app.factory('DataService', ['$http', function ($http) {
var entriesList = function () {
return $http.get("api/RestAzureTableMethods/retreiveEntities");
}
var updateEntity = function (elem) {
var data = angular.copy(elem);
var parameters = {
obj: JSON.stringify(data),
};
var config = {
params: parameters
};
return $http.get("api/RestAzureTableMethods/updateEntity", config);
}
var insertEntity = function (elem) {
var data = angular.copy(elem);
var parameters = {
obj: JSON.stringify(data),
};
var config = {
params: parameters
};
return $http.get("api/RestAzureTableMethods/insertEntity", config);
}
var deleteEntity = function (elem) {
var parameters = {
PartitionKey: elem.PartitionKey,
RowKey: elem.RowKey,
};
var config = {
params: parameters
};
return $http.get("api/RestAzureTableMethods/deleteEntity", config);
}
return {
entriesList: entriesList,
updateEntity: updateEntity,
deleteEntity: deleteEntity,
insertEntity: insertEntity
}
}]);
app.controller("MainCtrl", ["$scope", "DataService",
function ($scope, DataService) {
getEntriesList();
function getEntriesList() {
DataService.entriesList().then(function (response) {
$scope.entriesList = response.data;
});
}
$scope.updateEntity = function (elem) {
DataService.updateEntity(elem).then(function (response) {
getEntriesList();
});
}
$scope.deleteEntity = function (elem) {
DataService.deleteEntity(elem).then(function (response) {
getEntriesList();
});
}
$scope.insertEntity = function (elem) {
DataService.insertEntity(elem).then(function (response) {
getEntriesList();
});
}
}
]);
$(document).on("click", "#addbutton", function () {
//animation for opening and closing insertion form
$("#PanelToHide").fadeToggle();
});
</script>
Html code :
<div ng-app="myApp" ng-controller="MainCtrl">
<div class="row">
<div class="col-md-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Azure Table Content</h3>
<div class="pull-right">
<span class="clickable filter" id="addbutton" data-toggle="tooltip" title="Toggle table filter" data-container="body">
<i class="glyphicon glyphicon-plus-sign"></i>
</span>
</div>
</div>
<div id="PanelToHide" class="panel-body">
<center><label class="col-sm-12 control-label"><h3>Add new Entry</h3></label></center>
<form class="form-horizontal" id="formUploadFile" name="formUploadFile">
<div class="form-group">
<label class="col-sm-2 control-label">first Name</label>
<div class="col-sm-10">
<input type="text" ng-model="master.firstName" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">last Name</label>
<div class="col-sm-10">
<input type="text" ng-model="master.lastName" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" ng-click="insertEntity(master)" class="btn btn-default">Save</button>
</div>
</div>
</form>
</div>
<table class="table table-hover" id="dev-table">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th></th>
</tr>
</thead>
<tbody ng-repeat="elem in entriesList">
<tr>
<td><input type="text" ng-model="elem.firstName" /></td>
<td><input type="text" ng-model="elem.lastName" /></td>
<td><button type="button" ng-click="updateEntity(elem)" class="btn btn-default">edit</button>
<button type="button" ng-click="deleteEntity(elem)" class="btn btn-default">delete</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
3) Scenario of execution
- Show all entries :
- Insertion of new Entry :
- Update an exiting entry :
- Delete an existing entry :
No comments:
Post a Comment