In my previous article I talk about Azure Cosmos DB. In this post, I will describe in simple steps how you can deploy a web app with an Azure Cosmos DB on the back end.
Prerequisites :
- Azure Cosmos DB account with SQL API
- Azure Web App Service
- Visual Studio 2015 or Higher
Install Document DB NuGet Package
NuGet is a tool that helps developers to download compiled DLL’s “packages” for their solutions. In the image below, I download the Microsoft.Azure.DocumentDB package which I use it for the demo project.
Web.config Configuration (Connect to Azure Cosmos DB)
On Solution Explorer, select Web.config and add the following values, endpoint, authKey, database, collection.
<appSettings> <add key="webpages:Version" value="3.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> <!--Copy the value from the URI field. --> <add key="endpoint" value="https://cloudopszone.documents.azure.com:443/"/> <!--Copy the value from PRIMARY OR SECONDARY KEY field. --> <add key="authKey" value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"/> <!--Copy the value from PRIMARY CONNECTION STRING field. --> <add key="database" value="cloudopszone"/> <!--Copy the value from PRIMARY CONNECTION STRING field. --> <add key="collection" value="AdventureWorksData"/> </appSettings>
Repository Configuration
A repository works intermediary between business access layer and data access layer of the Web application. Below you can see the C# code that I used to create the WebAppCosmosDB.Repository.
namespace WebAppCosmosDB { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); CosmosDBRepository<Employee>.Initialize(); } } }
namespace WebAppCosmosDB.Repository { public class CosmosDBRepository<T> where T : class { private static readonly string DatabaseId = ConfigurationManager.AppSettings["database"]; private static readonly string CollectionId = ConfigurationManager.AppSettings["collection"]; private static DocumentClient client; public static void Initialize() { client = new DocumentClient(new Uri(ConfigurationManager.AppSettings["endpoint"]), ConfigurationManager.AppSettings["authKey"]); CreateDatabaseIfNotExistsAsync().Wait(); CreateCollectionIfNotExistsAsync().Wait(); } private static async Task CreateDatabaseIfNotExistsAsync() { try { await client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(DatabaseId)); } catch (DocumentClientException e) { if (e.StatusCode == System.Net.HttpStatusCode.NotFound) { await client.CreateDatabaseAsync(new Database { Id = DatabaseId }); } else { throw; } } } private static async Task CreateCollectionIfNotExistsAsync() { try { await client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId)); } catch (DocumentClientException e) { if (e.StatusCode == System.Net.HttpStatusCode.NotFound) { await client.CreateDocumentCollectionAsync( UriFactory.CreateDatabaseUri(DatabaseId), new DocumentCollection { Id = CollectionId }, new RequestOptions { OfferThroughput = 1000 }); } else { throw; } } } public static async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> predicate) { IDocumentQuery<T> query = client.CreateDocumentQuery<T>( UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId)) .Where(predicate) .AsDocumentQuery(); List<T> results = new List<T>(); while (query.HasMoreResults) { results.AddRange(await query.ExecuteNextAsync<T>()); } return results; } public static async Task<IEnumerable<T>> GetItemsAsync() { IDocumentQuery<T> query = client.CreateDocumentQuery<T>( UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId)) .AsDocumentQuery(); List<T> results = new List<T>(); while (query.HasMoreResults) { results.AddRange(await query.ExecuteNextAsync<T>()); } return results; } } }
Controllers Configuration
Controllers, responsibility is to control the way that interacts a user with an MVC App, for example, a user sends a request to a Web App and the controller define the response to send back.
Let’s take a quick look to the controller C# code.
public class EmployeeController : Controller { // GET: Employee public async Task<ActionResult> Index() { var items = await CosmosDBRepository<Employee>.GetItemsAsync(); return View(items); } }
Models Configuration
Models are used to represent data from a database to the Web interface on an ASP.Net project. For example, on the C# code below you can see the fields that will project on the Web App.
public class Employee { [JsonProperty(PropertyName = "BusinessEntityID")] public string BusinessEntityID { get; set; } [JsonProperty(PropertyName = "Title")] public string Title { get; set; } [JsonProperty(PropertyName = "FirstName")] public string FirstName { get; set; } [JsonProperty(PropertyName = "MiddleName")] public string MiddleName { get; set; } [JsonProperty(PropertyName = "LastName")] public string LastName { get; set; } }
Views Configuration
Actually, a View is a page that is used from a Web App. This is not a page that point to a path on a hard disk but is mapped to controller actions.
On the C# code bellow you can see the View for my example.
@model IEnumerable<WebAppCosmosDB.Models.Employee> @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>Index</h2> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.BusinessEntityID) </th> <th> @Html.DisplayNameFor(model => model.Title) </th> <th> @Html.DisplayNameFor(model => model.FirstName) </th> <th> @Html.DisplayNameFor(model => model.MiddleName) </th> <th> @Html.DisplayNameFor(model => model.LastName) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.BusinessEntityID) </td> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @Html.DisplayFor(modelItem => item.FirstName) </td> <td> @Html.DisplayFor(modelItem => item.MiddleName) </td> <td> @Html.DisplayFor(modelItem => item.LastName) </td> </tr> } </table>
Related links :