First WPF Application

The other day I found myself needing to open a 2 GB log file, something that neither Notepad nor Notepad++ could handle.  There are applications that can do this, but I didn’t feel like installing any of them, so I did what I usually do: hack something in Visual Studio, then discard.  I realized that my little hack of splitting up a big file into smaller files might make a nice desktop utility, so I decided to create an application to do this.  But which technology to use?

The hack was .NET code, so it had to be a Visual Studio project.  Use Windows Forms?  That’s in maintenance mode, and seems kind of passé.  How about Windows Presentation Foundation (WPF)?  Well, there’s a first time for everything…
WPF

WPF provides a nice level of familiarity to those with Win Forms experience.  There’s a toolbox of reusable controls to drag and position when creating the user interface.  These controls interact via events (so, so many of them) raised by the framework, or by user interaction.  Plus, plenty of properties on each control that can be set in the Properties window, or manipulated in code.  Where WPF diverges from Win Forms – and in my opinion obsoletes it – is in the areas of graphics rendering and transformations.

Graphics

The options provided by WPF to style elements directly in the IDE is an impressive selection of color pickers, mixers and brush gradients, that would take a ridiculous amount of code to achieve in Win Forms.  No waiting for your UI/UX team to create a background image, just start picking and dragging.

Transforms

WPF transforms allow us to control the rendering position of controls, for the purpose of animating them.  The Windows.Media.Transform library provides methods for manipulating the rotation, scale, skew and translation of controls.  For example, this code in Win Forms would’ve taken the creation of a complex custom control, with many moving parts:

private void ShowSpinner()
{
var animation = new DoubleAnimation(360, 0, new Duration(TimeSpan.FromSeconds(1)))
{
RepeatBehavior = RepeatBehavior.Forever
};
var rotate = new RotateTransform();
imgSpinner.RenderTransform = rotate;
rotate.BeginAnimation(RotateTransform.AngleProperty, animation);
imgSpinner.Visibility = Visibility.Visible;
}

But in WPF it’s as simple as defining the animation and transformations you want, then assigning it to the control.  Simple and powerful.

.NET

Despite all this GUI awesomeness, WPF is still a part of the .NET Framework, so the code-behind can use any libraries that are supported by your version of the Framework.  My little application leverages System.IO for file manipulation, System.Threading.Tasks for asynchronous work and Microsoft.Win32 for access to native Windows APIs.  Same old .NET code with a bitchin’ GUI on top.

XAML

I didn’t even touch on XAML, which is a markup language for declaratively describing the behaviors and interactions of a set of components.  XAML is a powerful beast of a thing, that promotes the clean separation of view from data.  It’s also not necessary to know to create a WPF application, and is way outside the scope of this post.  Sorry if you read this far hoping for some XAML knowledge to drop.

Code

So that sums up my first WPF application: familiar core .NET libraries providing functionality behind a user interface rendered by a cutting-edge graphics engine.

Here’s the code: https://github.com/LouisChiero/BigFileSplitter

Building A Full Stack Web Application – Part 5: The API

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

Enough about data and the framework, let’s take a look at the Stocks Tracker API, and see how information from previous posts have gotten us to this point.

The Stocks Tracker API needs to provide data to a variety of consumers, in a REST-ful way, accessible via the HTTP protocol.  Additionally, the API needs to be testable from HTTP tools such as Fiddler, cURL and Postman.

 

Goals

I had some goals to accomplish with the API project in Visual Studio.  First, include only packages and code necessary to get the API running.  That meant not including any assemblies from the MVC framework, which Visual Studio ASP.NET project templates include by default for documentation purposes, but cause project bloat, and deployment of “dead code.”  Besides, a tool like Swagger provides a simple and lightweight way to document your API, without turning it into a web site.

Another goal was to leverage the relationships ASP.NET Identity has with Entity Framework and OWIN/Katana to provide authentication & authorization functionality for the API.  The API needs to grant resource access only to those users properly authenticated and authorized by Identity.

Finally, I wanted to leverage existing financial APIs that provide quotes and news items for stocks and other securities.

 

Startup & Configuration

I started by adding a new class library project to the Stocks Tracker solution, named StocksTracker.API (lest there be any confusion as to what this project provides), followed by Global.asax and OWIN Startup classes from the project-level context menu.  These classes allow us hooks into an application’s startup process, so that we can configure the application appropriately.

In Global.asax, the mighty Autofac is configured to register dependencies in its DI container.  Autofac has a nice extension method that allows registration of all IHttpController implementations in a single line of code.  This is also where we configure the database connection from values in the Web.config file (these values are overridden during the deployment phase).  To keep things tidy, I also register any classes that the authorization middleware will need to communicate with the application.


// create IoC container
var builder = new ContainerBuilder();
// register all API controllers
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

// register stock tracker context as singleton
builder.Register(pcf => new StocksTrackerContextFactory(sqlConnectionBuilder, false))
 .As<IObjectFactory<StocksTrackerContext>>()
 .SingleInstance();

// register objects used in user authentication/authorization
builder.Register(provider => new ApplicationOAuthProvider(
 ConfigurationManager.AppSettings["Identity.PublicClientId"],
 _container.Resolve<IUserAdministration>()))
 .As<IOAuthAuthorizationServerProvider>()
 .SingleInstance();

// register object that communicates between application and middleware authorization server
builder.Register(options => new OAuthAuthorizationServerOptions
{
 TokenEndpointPath = new PathString(ConfigurationManager.AppSettings["Identity.TokenEndpointPath"]),
 AuthorizeEndpointPath = new PathString(ConfigurationManager.AppSettings["Identity.AuthorizeEndpointPath"]),
 AccessTokenExpireTimeSpan = TimeSpan.FromDays(days),
 AllowInsecureHttp = true,
 Provider = _container.Resolve<IOAuthAuthorizationServerProvider>()
})
 .As<OAuthAuthorizationServerOptions>()
 .SingleInstance();

ASP.NET allows global configuration via the GlobalConfiguration static class.  Here is where we set Autofac as the default dependency resolver, and register any routes the API will expose (routing in Web API and MVC is an art unto itself. I prefer to use class- and method-level attributes to define application routes, instead of using the template collection, which is fragile and not intuitive).

Set Dependency Resolver:


// build container, and set dependency resolver
_container = builder.Build();
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(_container);

Define Routes:


// build container, and set dependency resolver
GlobalConfiguration.Configure(WebApiConfig.Register); // in Global.asax.cs
 config.MapHttpAttributeRoutes(); // in WebApiConfig.Register

Startup.cs is where ASP.NET recommends adding middleware to an application, and Stocks Tracker is no different.  OWIN passes an IAppBuilder object to the Startup class, and it’s here that the OWIN “pipeline” is constructed by adding modules to the builder.  Each module is constructed in such a way that it either processes the incoming HTTP request, or passes control to the next module until one or none have processed the request.  Besides OWIN middleware, there are many third-party modules available via NuGet, plus it’s easy to write your own custom middleware.


public void ConfigureAuth(IAppBuilder app)
{
  // Enable the application to use a cookie to store information for the signed in user...
  app.UseCookieAuthentication(new CookieAuthenticationOptions());
  
  // ...and to use a cookie to temporarily store information about a user logging in with a third party provider
  app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
  
  // Enable the application to use bearer tokens to authenticate users
  app.UseOAuthBearerTokens(OAuthOptions);
}

 

Authentication/Authorization

As seen above, the API is now configured with OWIN middleware that will a) allow authentication of a registered user, storing the user’s credentials in a browser cookie; b) allow authentication of an external user, storing external access information in a browser cookie; and, c) require OAuth bearer tokens for access to restricted resources.

OAuth allows users access to our resources, provided they are authenticated by a third party such as Google, Twitter, Microsoft or Facebook.  OWIN middleware decouples all of this from the application, reducing the process to a client/server interaction, with our API acting as the client, and OWIN in the server role.  OWIN provides a wide range of configuration options, which are then passed to the middleware.

Here is a simple OWIN configuration example from the Stocks Tracker API: Create an instance of OAuthAuthorizationServerOptions to populate the OWIN OAuth middleware server with some default values.  Include a custom provider derived from OAuthAuthorizationServerProvider to listen for and act on messages from the server.  The server options instance is passed to the middleware by the UseOAuthBearerTokens() method during startup.

Pretty complicated stuff, but worth a deep dive, especially since OAuth is the standard for third party website authorization.

 

Services
In the last post we explored the Framework project of interfaces and POCOs, and the API is where they get put to work.  Basically, each service is an implementation of a Framework interface, and each is registered with Autofac in the configuration phase for dependency injection.  The methods do little more than query Entity Framework for data, given the criteria passed to the method, and return collections of POCO objects for the API to serialize for its callers.


public class StockTrackersService : IStockTrackers
{
  // constructor with dependencies injected
  public StockTrackersService()
  
  public async Task<StockTrackerRecord> GetStockTrackerAsync(int stockTrackerId)
  {
    using (var ctx = _stocksTrackerContextFactory.GetObject())
    {
      // take advantage of async/await
      return await ctx.StockTrackers
      .SingleOrDefaultAsync(tracker => tracker.StockTrackerId == stockTrackerId);
    }
  }
}

The UserAdministration service, however, is declared entirely within the API project, so as not to add an unnecessary Identity dependency to Framework.  Most examples and project templates instantiate Identity’s UserManager, UserStore, RoleManager and RoleStore classes all over the place, so UserAdministration is a nice facade to isolate and expose Identity functionality through a common interface.

Of note are three services that rely on third party APIs for quote, headline and chart data.  These services provide wrappers around the third party APIs, so that the resources are consumed in a manner consistent with the EF services.  They are all public APIs from Yahoo! Finance:

Quotes

Headlines:

Charts:

Cool.

 

Controllers

By convention, an ASP.NET Web API controller defines methods that correspond to an HTTP request by returning an appropriate IHttpActionResult implementation.  The Stocks Tracker API will do the same, with a controller for each service, providing methods for each HTTP verb (GET, POST, PUT, DELETE, etc.) necessary.

The Stocks Tracker controllers will take advantage of the wide range of helper methods and properties provided by the abstract ApiController base class, which include helpers for data validation, IHttpActionResults and users.  Each method will take advantage of .NET’s async/await functionality, which will help keep the API responsive.

These controllers are really the culmination of all the work up to this point: The routing engine routes an authenticated HTTP request to the appropriate API controller, which responds by returning data retrieved from a service call, or an appropriate error response.  StockTrackersController is a good example, as it has an action method for each of the major HTTP verbs, has its routing and authorization controlled declaratively, and has its dependencies injected by the global dependency resolver.


[Authorize] <- attribute enforces only authorized access to this controller's resources
[RoutePrefix("api/StockTrackers")] <- attribute defines the base route for this controller's actions
public class StockTrackersController : ApiController
{
  // this controller's service dependency
  private readonly IStockTrackers _stockTrackers;
  // constructor injection
  public StockTrackersController(IStockTrackers stockTrackers)
  {
     _stockTrackers = stockTrackers;
  }

  // GET api/StocksTrackers <- the route for this GET action
  [HttpGet] <- attribute enforces HTTP GET requests only
  [Route] <- attribute defines this route as the base route
  public async Task<IHttpActionResult> Get()
  {
    // ask the service for the user's stock trackers
    var stockTrackers = await _stockTrackers.GetStockTrackersForUser(User.Identity.GetUserId());
    // return an Ok action result (HTTP response 200) with data
    return Ok(stockTrackers.Select(MapStockTrackerRecordToObject));
  }

  // GET api/StockTrackers/1 <- the route for this GET action
  [HttpGet]
  [Route("{id:int}", Name = GetStockTrackerRouteName)] <- attribute defines base route plus mandatory parameter type
  public async Task<IHttpActionResult> Get(int id)
  {
    // return BadRequest action result (HTTP response 400)
    if (id == 0)
      return BadRequest();

    // return Ok action result with data
    // or NotFound (HTTP response 404)
  }

  // POST api/StockTrackers/Create <- the route for this POST action
  [Route("Create")] <- attribute defines base route plus "Create"
  [HttpPost] <- attribute enforces HTTP POST requests only
  public async Task<IHttpActionResult> Create(StockTrackerModel model)
  {
    // return BadRequest action result if model fails validation
    if (!ModelState.IsValid)
      return BadRequest(ModelState);

    // return Created action (HTTP response 201) with new data
    var newStockTracker = await _stockTrackers.AddStockTrackerForUserAsync(model0;
    return Created(newStockTracker);
  }

  // DELETE api/StockTrackers/1 <- the route for this DELETE action
  [Route("{id:int}")] <- attribute defines base route plus mandatory parameter type
  [HttpDelete] <- attribute enforces HTTP DELETE requests only
  public async Task<IHttpActionResult> Delete(int id)
  {
    // delete and return empty Ok action result
    await _stockTrackers.RemoveStockTrackerAsync(id);
    return Ok();
  }

  // PUT api/StockTrackers/1 <- the route for this PUT or PATCH action
  [HttpPatch] <- attribute enforces PATCH requests
  [HttpPut] <- attribute enforces PUT requests
  [Route("{id:int}")] <- attribute defines base route plus mandatory parameter type
  public async Task<IHttpActionResult> Put(int id, UpdateStockTrackerModel model)
  {
    // update and return Ok result with data
    var stockTracker = await _stockTrackers.UpdateStockTrackerAsync(model);
    return Ok(stockTracker);
  }
}

 

It’s worth noting the roles Identity and OWIN play behind the scenes with API controllers.  Any route that is decorated with an Authorize attribute requires
authentication and authorization of the request.  This is done is by looking for an access token in the HTTP Authorization header (OWIN), and attempting to match the token to a user (Identity via Entity Framework).  An authentication or authorization failure will result in a 401 Unauthorized response code returned to the caller.  Decorating a method with an AllowAnonymous attribute allows unauthorized access to the resource, provided the route is a match.

 

Testing

Sure, I had a nice API now, but how was I going to test it without a UI?  Thanks to www.asp.net (a HUGE influence on this project, and an invaluable resource) and Pluralsight (ditto) I checked out Fiddler, which allowed me to send test HTTP requests to my API.  Using examples from these resources I was able to register a user with the API, request an access token, then use the token to request access to restricted resources.  And just like that, my li’l API was returning me data!  Hot dog.

 

Summary

So now I have a working API able to perform CRUD actions in a REST-ful manner via HTTP.  In theory this API should be able to provide data to any number or clients including the web/mobile web (ASP.NET MVC, ASP.NET Web Forms, AngularJS, Aurelia, KnockoutJS, ES2015), hybrid apps (HTML/JavaScript/CSS in a view, wrapped by native APIs), or purely native apps for Anroid iOS or UWP.

Oh, and one other thing: Converting all this to ASP.NET Core will be almost a total rewrite.  Oh, well.

 

Up next: a UI!

Building A Full Stack Web Application – Part 4: The Framework

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

Let’s do an easy one.  The framework is a class library project that contains interfaces and POCOs that represent the business operations and data.  Each interface is a contract to which each implementation must adhere.  The POCOs (or DTOs, or property bags) are simple classes, whose job it is to transfer data to and from the business operations.

Interfaces

For Stocks Tracker, I want to define some operations that can be performed by callers.  For example, I want a caller to be able to retrieve a stock by either integer key ID, or by a unique ticker value:

public interface IStocks
{
  /// <summary>
  /// Asynchronously queries a stock for the given ID.
  /// </summary>
  /// <param name="stockId">The stock ID.</param>
  /// <returns>A <see cref="StockRecord"/> object, or null if not found.</returns>
  Task<StockRecord> GetStockAsync(int stockId);

  /// <summary>
  /// Asynchronously queries a stock for the given ticker symbol.
  /// </summary>
  /// <param name="tickerSymbol">The stock ticker symbol.</param>
  /// <returns>A <see cref="StockRecord"/> object, or null if not found.</returns>
  Task<StockRecord> GetStockAsync(string tickerSymbol);
}

Any implementations of this interface will have to return an asynchronous operation that resolves to a stock matching the passed in parameter.

POCOs

Data is a different story.  I don’t want to return a “live” object, that is wired to Entity Framework for some caller to monkey around with.  Instead, the return object will be a class of primitive types (integers and strings, and perhaps other POCO classes), representing data in a format that makes sense to the operation being performed.  Another benefit of these simple classes is that they are easily serializable by whatever protocol is being used to call the business operation:

public class StockRecord : IEquatable<StockRecord>
{
  /// <summary>
  /// Gets and sets the stock record id value.
  /// </summary>
  public int StockRecordId { get; set; }

  /// <summary>
  /// Gets and sets the ticker symbol value.
  /// </summary>
  public string TickerSymbol { get; set; }

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

That’s pretty much it. It’s good practice to keep your business layer interfaces and data classes in a reusable project, that can be reused for multiple implementations.
Next, we’ll see the framework in action at the API layer.

Building A Full Stack Web Application – Part 3: Data Context

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

Microsoft’s Entity Framework (EF) is built around the concept of a data context, which is essentially a bridge between a database and classes, allowing us to interact with data as objects.  The EF class DbConext allows us to query and persist data in an object-oriented way, without having to deal with yucky SQL statements, database connection strings or transactions.

Context 

Back to Stocks Tracker.  Now that the data was modeled I added another class library project – Data.Context – which would be responsible for generating the database tables, keys and indexes, as well as seeding the database with any reference data.  This project provides a custom abstraction of DbContext, available to other layers.

But wait.  Remember how in a previous post, I showed how Microsoft’s Identity framework can be used to generate security classes that work hand-in-hand with Identity?  Well Identity also provides its own implementation of DbContext, IdentityDbContext, which allows us to interact with security data as objects.  Since I want to be able to query security objects via EF, the Stocks Tracker context will actually be derived from IdentityDbContext.

Let’s look a little closer at the context Stocks Tracker exposes to its callers.


/// <summary>
/// Class provides access to Entity Framework CRUD actions within the Stocks Tracker domain.
/// </summary>
public class StocksTrackerContext : IdentityDbContext<ApplicationUser>, IStocksTrackerContext

As you can see, StocksTrackerContext implements IdentityDbContext, which will use the ApplicationUser class defined in the Data.Models project. StocksTrackerContext also implements an interface, so that callers are limited to the data I want them to see.

public StocksTrackerContext()
: base("name=StocksTrackerContext")
{
}

public StocksTrackerContext(string connectionString, bool eagerOpen)
: base(connectionString)
{
_eagerOpen = eagerOpen;
if (eagerOpen)
Database.Connection.Open();
}

The constructors for DbContext are interesting.  Passing “name=StocksTrackerContext” forces EF to search the project for a connectionStrings node in a configuration file, and attempts to use the connection string matching the name to connect to the database.  The context can throw errors when called from a different project without a configuration file, so rather than duplicate config values all over the place, I prefer the second constructor, where an explicit connection string can be provided.


public IDbSet<Stock> Stocks
{
get { return _stocks ?? (_stocks = Set<Stock>()); }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new StockConfiguration());
modelBuilder.Configurations.Add(new StockTrackerConfiguration());
modelBuilder.Configurations.Add(new StockTrackerStockConfiguration());
base.OnModelCreating(modelBuilder);
}

EF provides its own implementation of IEnumerable in the generic IDbSet interface.  This provides LINQ functionality on the collection, but with the ability to add and remove objects from the underlying collection.

But first we need a database.  EF provides a ton of configuration options for dealing with data, but I like to keep it simple.  Basically it boils down to configuring your entities, and migrating your data.  For configuration, EF provides a generic base class EntityTypeConfiguration, which for a model allows you to set constraints on tables (keys, name) and columns (size, nullability).

Configuration

/// <summary>
/// Defines the entity type configuration for the <see cref="Stock"/> domain model.
/// </summary>
public class StockConfiguration : EntityTypeConfiguration<Stock>
{
/// <summary&amp;gt;
/// Instantiates the StockConfiguration class.
/// </summary&amp;gt;
public StockConfiguration()
{
HasKey(s => s.StockId);

Property(s => s.TickerSymbol)
.IsRequired()
.HasMaxLength(10);

Property(s => s.OpenPrice)
.IsOptional()
.HasPrecision(8, 2);

HasMany(s => s.StockTrackerStocks)
.WithRequired(sts => sts.Stock)
.HasForeignKey(fk => fk.StockId);

ToTable("Stock");
}
}

With this in place EF has what it needs to translate a configuration class into DDL statements used to create or update a database schema.  Plus, EF tracks schema changes for you, and will automatically drop or add columns as the configuration class evolves.

Migration

For migrating data, EF provides an extensible base class DbMigrationsConfiguration, which requires a generic class of type DbContext.  This is where you would pass your custom implementation of DbContext, for this example StocksTrackerContext.

DbMigrationsConfiguration provides a single overridable method called Seed, passing the concrete implementation of DbContext.  From there any statements needed to “seed” the database with reference data or default users can be executed via the context.


/// <summary>
/// Class for migrating data to the Stocks Tracker domain.
/// </summary>
public class StocksTrackerMigrationsConfiguration: DbMigrationsConfiguration<StocksTrackerContext>

protected override void Seed(StocksTrackerContext context)
{
   // query, add, edit or delete data as needed
}

Initialization

With the context, configuration and migration classes in place, all that’s missing is a process that ties them all together.  Luckily, EF provides a number of options for initializing the database.  For Stocks Tracker I used the MigrateDatabaseToLatestVersion initializer, which is able to detect configuration changes and update the database schema accordingly (the Seed method will also be called during this process).


Database.SetInitializer(
 new MigrateDatabaseToLatestVersion<StocksTrackerContext, StocksTrackerMigrationsConfiguration>());

What’s nice about this is that the initialization can be called from within some bootstrapping code, or compiled into an executable called during an installation or some other process. I made a simple console project that initializes the database, then writes data to the console, so I know when there’s an error with the configuration or migration. The options EF provide make it easy to configure the database and context to work in development, testing or production environments.

Summing Up

As I mentioned, EF provides many options for creating a context that allows your application to connect to a data store, including the exact opposite of what the Stocks Tracker does (starting with a created and populated database, then generating configuration and context classes).

One cool option is Simon Hughes’ Reverse POCO Generator, which given an existing database will reverse engineer and generate POCO, configuration and context classes from tables and views, and will even generate classes for using stored procedures.  A familiarity with T4 templates is a big help, as most generators leverage T4s to some extent.

That was a lot to cover, but it’s enough for what I want Stocks Tracker to accomplish.  Next, we’ll look at the business layer.

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!