Building A Full Stack Web Application – Part 2: Modeling the Data

This post is a continuation in a series about building a full stack web application.  Previous posts in the series:

There were a couple of goals I wanted to accomplish with the Stocks Tracker data.  The first goal was to keep any data access or modeling classes isolated in their own projects, accessible only through abstractions, so that any layer(s) reliant on data would have no knowledge of how the underlying data store worked.  The second goal was to leverage Microsoft’s Entity Framework (EF) and Identity frameworks.

Models

For data modeling, I added a new class library project to the Stocks Tracker solution, and called it Data.Models.  The data model was pretty simple, and only required adding a few NuGet packages, so that EF and Identity could work together:


<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.1.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.0.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.EntityFramework" version="2.0.1" targetFramework="net45" />
</packages>

The classes were simple POCOs that EF needs to define and map entity relationships to an underlying data store.  Pretty standard stuff, if you prefer EF’s code-first approach to generating database schemas.  However, throw in Identity and EF will also generate objects used by the Identity framework for security, such as tables to store user accounts, as well as support for third-party logins, such as Google, right out of the box.  Which is pretty cool, and necessary for a modern Web application.

The only thing needed was to create a class derived from IdentityUser, and EF is smart enough to create a security schema containing all the IdentityUser properties, as well as any custom properties defined in the derived class.  Mine adds the properties FirstName and LastName, which will be added as columns to the table AspNetUsers.


/// <summary>
/// Encapsulates the properties of an application user object.
/// </summary>
public class ApplicationUser : IdentityUser
{
/// <summary>
/// Instantiates the ApplicationUser class.
/// </summary>
public ApplicationUser()
{
}

/// <summary>
/// Gets and sets the first name value.
/// </summary>
public string FirstName { get; set; }

/// <summary>
/// Gets and sets the last name value.
/// </summary>
public string LastName { get; set; }
}

And that’s it for data modeling.  Up next, the data context.

Building A Full Stack Web Application – Part 1: Why

When I made the decision to move my career away from Windows desktop application development to web-based programming, I had a monumental task ahead of me.  I had almost zero knowledge of how the Web worked.  I knew a little bit of HTML; JavaScript was clunky, to be avoided at all cost; and CSS was a complete mystery.

To make matters worse, my first foray into the Web was trying to learn ASP.NET’s Web Forms.  Man, did that suck.  A confusing melding of tightly coupled business logic, DOM element manipulation and styling (sometimes even JavaScript!) smashed into a code-behind file, along with an “HTML” page of elements that talked to the code-behind (or didn’t).

Throw in a confusing encapsulation of the request/response cycle as a series of page-level events, plus controls that rendered HTML in a black box, and what you got was a working web page with no knowledge of the Web.  Instead, you just learned Web Forms.  No dice.

Enter ASP.NET MVC.  Now this was something I could sink my teeth into!  An architecture that embraced a clean separation of responsibilities by following the Model-View-Controller design pattern.  Absolute control over the HTML rendered.  An unobtrusive method of client/server communication via the Razor syntax.  A design that favored a “convention vs. configuration” model, but was still easily extensible.

Still, most MVC training and guides crammed everything from data access to business logic into the controllers, making them an untestable mess.  I was coming from a world of software best practices, that embraced the SOLID principles, as well as putting a premium on unit testing.  Could I apply these practices and methodologies to web applications as successfully as I had to desktop applications?

Well, I was going to give it a shot.  After a lot of thought and research I came up with an idea for an application, and a plan of making it happen.  The application would be structured in the classic layers of a full stack platform: data layer; business layer; API; presentation/UI layer; and a network layer for hosting the whole thing.

Microsoft technologies would provide a measure of familiarity, but open source packages would be used where appropriate.  For source control, I chose GitHub due to its cost (nothing) and ease.  My IDE would be Visual Studio, and my database SQL Server.  Autofac would be my IoC container, as it was made to work with the .NET Framework.

My application would allow people to search for and track their favorite stocks.  I would imaginatively name it the Stocks Tracker.  This is how I built it.

Up first, the data layer.

ASP.NET MVC Role-Based Links

Sometimes a web site needs to limit access to its services based on a user’s role.  ASP.NET MVC allows you to leverage role-based security so that links are shown or hidden based on a user’s privileges.  And all with no JavaScript!

First, in your _Layout.cshtml file add Razor code to render any links that should be visible to authenticated users, like so:

<nav>
  <ul>
    <li>@Html.ActionLink("Home", "Index", "Home")</li>
  </ul>
</nav>

Next, add an action to the Home controller that will query roles assigned to the user.  We will use the controller’s ViewBag property to record which links will be available or hidden.

[ChildActionOnly]
public ActionResult CheckForPrivilegedPermissions()
{
  // check if user is allowed to access functionality that requires elevated privileges
 if (User.Identity.IsAuthenticated)
 {
    IEnumerable<Role> userRoles
      = _authService.GetRolesForUser(User.Identity.Name).ToList();

    ViewBag.ShowNewRecordLinks = userRoles.Contains(Role.Creator);
    ViewBag.ShowUserAdminLinks = userRoles.Contains(Role.UserAdmin);
    ViewBag.ShowViewRecordsLinks = userRoles.Contains(Role.Reader);

    // show the links
    return PartialView("_PrivilegedLinks");
 }

 // return nothing
 return new EmptyResult();
}

This action will return an EmptyResult if the user is not authenticated. Otherwise, it will return a PartialView result, which injects a snippet of HTML into the markup. Let’s look at this partial view, named _PrivilegedLinks.cshtml.

@if (ViewBag.ShowNewRecordLinks == true)
{
 <li>
   <a href="#">Add New</a>
   <div>
     @Html.ActionLink("This", "Add", "This")
     @Html.ActionLink("That", "Add", "That")
     @Html.ActionLink("Other", "Add", "Other")
   </div>
 </li>
}
@if (ViewBag.ShowViewRecordsLinks == true)
{
 <li>
  <a href="#">View</a>
  <div>
     @Html.ActionLink("This", "Index", "This")
     @Html.ActionLink("That", "Index", "That")
     @Html.ActionLink("Other", "Index", "Other")
   </div>
 </li>
}
@if (ViewBag.ShowUserAdminLinks == true)
{
 <li>
   @Html.ActionLink("User Admin", "Index", "UserAdmin")
 </li>
}

Here the ViewBag values set in the Home controller dictate the HTML the partial view will render.  To tie the whole thing together, return to _Layout.cshtml and add a Razor helper that will call the controller action each time a page is loaded.

<nav>
  <ul>
    <li>@Html.ActionLink("Home", "Index", "Home")</li>
    <!-- new -->
    @Html.Action("CheckForPrivilegedPermissions", "Home")
  </ul>
</nav>

And that’s that.  Dynamically rendered links based on user permission levels, and all done with basic functionality provided by the MVC framework.

I hope you enjoyed my first post.  Thanks for reading it!