Reading Time: 3 minutes

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 :

 

Share This