In this exercise you will create a simple ASP.NET MVC web application that will process the data you exported in the previous exercise.
-
Create a new project:
-
Open Visual Studio, and select File > New > Project. In the New Project dialog, do the following:
-
Select Templates > Visual C# > Web.
-
Select ASP.NET Web Application (.NET Framework).
-
Enter EmailMetrics for the Name of the project.
Note: Ensure that you enter the exact same name for the Visual Studio Project that is specified in these lab instructions. The Visual Studio Project name becomes part of the namespace in the code. The code inside these instructions depends on the namespace matching the Visual Studio Project name specified in these instructions. If you use a different project name the code will not compile unless you adjust all the namespaces to match the Visual Studio Project name you enter when you create the project.
-
Select OK. In the New ASP.NET Web Application Project dialog, select MVC and select OK.
-
-
Add and configure Azure Storage as a connected service:
-
In the Solution Explorer tool window, right-click the Connected Services node and select Add Connected Service.
-
On the Connected Services dialog, select Cloud Storage with Azure Storage.
-
On the Azure Storage Dialog, select the storage account where you exported the data to in the previous exercise and select Add.
This will install the necessary NuGet packages for the project.
-
-
Create a new model class that will be used to store the email metrics and in the view of the web application.
-
In the Solution Explorer tool window, right-click the Models folder and select Add > Class.
-
In the Add New Item dialog, select Class, set the name of the file to EmailMetrics.cs and select Add.
-
Add the following code to the class EmailMetrics you just created:
public string Email; public double RecipientsToEmail;
-
-
Create a new controller that will calculate and display the results of processing the emails exported in the previous exercise.
-
Right-click the Controllers folder and select Add > Controller:
-
In the Add Scaffold dialog, select MVC 5 Controller - Empty and select Add.
-
When prompted, name the controller EmailMetricsController and select OK.
-
Add the following
using
statements after the existingusing
statements at the top fo the file containing theEmailMetricsController
class:using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; using Newtonsoft.Json.Linq; using System.Configuration; using System.IO; using System.Threading.Tasks;
-
Add the following code to the
EmailMetricsController
class. These will be used to connect to the Azure Storage Account that contain the exported data:CloudStorageAccount _storageAccount; CloudBlobClient _storageClient; CloudBlobContainer _storageContainer;
-
Add the following method to the
EmailMetricsController
class. This will process an Azure blob and return back a object representing the email account and how many recipients there were combined across all emails found for the extracted account:private Models.EmailMetric ProcessEmail(CloudBlob emailBlob) { var emailMetric = new Models.EmailMetric(); using (var reader = new StreamReader(emailBlob.OpenRead())) { string line; while ((line = reader.ReadLine()) != null) { var jsonObj = JObject.Parse(line); // extract sender var sender = jsonObj.SelectToken("Sender.EmailAddress.Address")?.ToString(); // extract and count up recipients var totalRecipients = 0; totalRecipients += jsonObj.SelectToken("ToRecipients").Children().Count(); totalRecipients += jsonObj.SelectToken("CcRecipients").Children().Count(); totalRecipients += jsonObj.SelectToken("BccRecipients").Children().Count(); emailMetric.Email = sender; emailMetric.RecipientsToEmail = totalRecipients; } } return emailMetric; }
-
Add the following method to the
EmailMetricsController
class. This will enumerate through all blobs in the specified Azure Storage account's specified container and send each one toProcessEmail()
method added in the last step:private List<Models.EmailMetric> ProcessEmails() { var emailMetrics = new List<Models.EmailMetric>(); // connect to the storage account _storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["AzureStorageConnectionString-1"]); _storageClient = _storageAccount.CreateCloudBlobClient(); // connect to the container _storageContainer = _storageClient.GetContainerReference("maildump"); // get a list of all emails var blobResults = _storageContainer.ListBlobs(); // process each email foreach (IListBlobItem blob in blobResults) { if (blob.GetType() == typeof(CloudBlockBlob)) { var cloudBlob = (CloudBlockBlob)blob; var blockBlob = _storageContainer.GetBlobReference(cloudBlob.Name); var emailMetric = ProcessEmail(blockBlob); // if already have this sender... var existingMetric = emailMetrics.FirstOrDefault(metric => metric.Email == emailMetric.Email); if (existingMetric != null) { existingMetric.RecipientsToEmail += emailMetric.RecipientsToEmail; } else { emailMetrics.Add(emailMetric); } } } return emailMetrics; }
-
Add the following action to the
EmailMetricsController
that will use the methods added this class to process the emails and send the results to the view:[HttpPost, ActionName("ShowMetrics")] [ValidateAntiForgeryToken] public async Task<ActionResult> ShowMetrics() { var emailMetrics = ProcessEmails(); return View(emailMetrics); }
-
-
Create a new view for the EmailMetrics Index action:
-
In the Solution Explorer tool window, right-click the Views > EmailMetrics folder and select Add > View.
-
In the Add View dialog, set the View name to Index, leave the remaining input controls to their default values and select Add.
-
Update the markup in the new Views/EmailMetrics/Index.cshtml to the following. This will add a form with a single button that will submit an HTTP POST to the custom controller action added in the last step:
@{ ViewBag.Title = "Index"; } <h2>Email Metrics</h2> This application will look at the email data for emails extracted to the Azure Blob Storage account and display the total number of recipients from each sender. @using (Html.BeginForm("ShowMetrics", "EmailMetrics", FormMethod.Post)) { @Html.AntiForgeryToken() <div> <button type="submit">View email metrics</button> </div> <div> <em>Please be patient as this can take a few moments to calculate depending on the size of the exported data...</em> </div> }
-
-
Create a new view for the EmailMetrics ShowMetrics action:
-
In the Solution Explorer tool window, right-click the Views > EmailMetrics folder and select Add > View.
-
In the Add View dialog, set the following values and leave the remaining input controls to their default values and select Add:
- View name: ShowMetrics
- Template: List
- Model class: EmailMetrics (EMailMetrics.Models)
-
Update the markup in the new Views/EmailMetrics/ShowMetrics.cshtml to the following. This will display the results of the calculations.
@model IEnumerable<EmailMetrics.Models.EmailMetric> @{ ViewBag.Title = "ShowMetrics"; } <h2>Email Metrics</h2> <table class="table"> <tr> <th>Sender</th> <th>Number of Recipients</th> </tr> @foreach (var item in Model) { <tr> <td>@Html.DisplayFor(modelItem => item.Email)</td> <td>@Html.DisplayFor(modelItem => item.RecipientsToEmail)</td> </tr> } </table>
-
-
Update the navigation to have a way to get to the new controller:
-
In the Solution Explorer tool window, locate and open the file Views/Shared/_Layout.cshtml.
-
Replace the following line...
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
... with the following line to update the menu item:
<li>@Html.ActionLink("Email Metrics", "Index", "EmailMetrics")</li>
-
-
Test the application:
-
In Visual Studio, select Debug > Start Debugging.
-
When the application is built and loads in a new browser window, select the Email Metrics item in the top navigation bar.
-
On the Email Metrics page, select the View email metrics button.
-
When the page loads, you will see a list of emails addresses that were found among all emails with a sum of all the recipients sent between them, as shown from a small sample set in a test email extract in the following figure.
-