The MVC pattern
First I am going to discuss the basics of the MVC architectural pattern. Design-patterns in software development represent re-usable solutions for different kinds of usage-scenarios. To learn more about software design-patterns, please read this article on Code-Project:
Building an application using design patterns and principles in C#
Here is the general definition of the MVC pattern according to Wikipedia:
Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.The central component, the model, consists of application data, business rules, logic and functions. A view can be any output representation of information, such as a chart or a diagram. Multiple views of the same information are possible, such as a bar chart for management and a tabular view for accountants. The third part, the controller, accepts input and converts it to commands for the model or view
Just to avoid any confusion between ASP .NET MVC and MVC: ASP .NET MVC was named after the design-pattern and not the other way around.
Let’s dissect this definition. We have this three major players:
- The View
- The Model
- And the Controller
Everything that is related to display data in a way that users can consume (Websites, desktop apps, mobile apps etc.) is called a view. A view can also be a simple text output within a console application It’s purpose is simple: Display the data to the user!. But how is the data pumped into the view?
This is where the controller opts-in. The controller is responsible to render the view using a view-engine or not. If we map this to a basic ASP .NET application that would be the Razor view engine. This depends on the configuration. The controller could use a custom-implemented view-engine as well.
Basically the controller accesses the model, reads data from the model and creates it’s own sub-models (atomic projections based on your queries) that are returned to the view. The view grabs the data and renders it for the user into a human-readable form (or not – lol). The business logic, the Wikipedia definition talks about can – but does not have to – be implement within the model. Your database model could (but has not to) implement specific rules based on relations between your entities (tables) and for example using specific stored procedures and triggers on your database server to ensure a a workflow according to your real-world business rules.
In the real-world, most of the decision-logic is implemented within the controller-methods. This includes simple things like “Is the user account valid?”, “Is the user account locked ?” or more complex rules like “The user is able to send a specific amount of messages. After the quota exceeds he needs to upgrade his account”. And ASP .Net MVC is not an exception.
Here is a simplified diagram showing you the major players in a typical ASP .Net MVC web-app:
Again: This diagram is a simplification. It omits components like the authorization and authentication parts and much more. If you are interested in an in-depth explanation of the involved components and the life-cycle of a MVC5 app, I strongly suggest to visit this page:
Lifecycle of an ASP .NET MVC5 application
There is a link to an PDF document on this page that contains a very detailed diagram about the app-lifecycle and the involved components.
So far so good, let’s now jump to the next evolutionary steps.
Web API, OWIN and Katana
With the growing popularity of REST-API’s (Representational state transfer) the guys at Redmond had to react and give their developers the possibility to implement custom API’s that can be completely decoupled from the existing ASP .NET API. This lead to the implementation of the Web API framework.
The Web API framework allows developers to implement custom API’s that can be completely independent of the ASP .NET stack and follow the REST-based industry standards. To make it even more interesting and versatile, Redmond implemented a complete hosting environment that can host Web API and other functional components also called “Middleware” independently from any type of web-server including IIS (Internet Information Server): Katana.
Katana is based on the OWIN standard that is defined as follows:
OWIN defines a standard interface between .NET web servers and web applications. The goal of the OWIN interface is to decouple server and application, encourage the development of simple modules for .NET web development, and, by being an open standard, stimulate the open source ecosystem of .NET web development tools.
The steps to self-host your own Web-API using Katana are quite simple and very well documented by the ASP .NET team. Please read this article to learn how to self-host Web API:
Use OWIN to Self-Host ASP.NET Web API 2
If you want to get a deep insight into the Katana/OWIN implementation, you can read this extensive whitepaper:
An Overview of Project Katana
But be warned, after reading this you will be running naked on the street screaming “Katana! Katana! Katana!”
The best thing you can do to really understand the Katana implementation and to keep up with the latest changes, you should take a look at the source:
The Katana Project on CodePlex
Your first managed backend service
It’s time now to create your first managed backend service. Fire-up Visual Studio and create a new Project. Within the “New Project” dialog choose “cloud” and then on the right-hand side “Windows Azure Mobile Service”. Name your service “OldSchoolBeats” (or whatever you like) and hit “Ok”.
The “New ASP .NET Project” dialog will pop-up. Select “Azure Mobile Service” within the “Select a template” list and hit “Ok”. You cannot change any of the additional parameters.
Visual Studio is now going into “project-rollout-mode” preparing all the necessary files for you. After finishing it’s magic, Visual Studio presents you a basic managed backend project. We talked about the structure already in part one of this series. Let’s move on and customize our model.
The idea is to have a database of Old-School rap-artists. I have grabbed some data from ALL MUSIC (they have an excellent database). Please remember that this content is copyrighted and therefore I am not including it into my content. Just visit the link and copy the data for testing or create your own set of database records.
Updating to the latest bits
Before we start, we need to update some assemblies using NuGet. Please don’t update ALL assemblies, this will render your service unusable. Right-Click on “References” choose “Mange NuGet packages”. Within the Nuget-Packager dialog select “Updates” on the left and scroll down to the end. Update only two packages “Windows Azure Mobile Services .NET Backend” and “Windows Azure Mobile Services .NET Backend Entity Framework Extensions” . Leave the rest as-is for now.
If you now try to build the project, VS will complain, that it could not copy the AutoMapper.Net4.dll because it could not find it. There is a quirk here within the VS project-file. It is looking for version 3.1.1, but we are running already 3.2.0.
To fix this, right-click the “OldSchoolBeatz” project and select “Unload Project”. After the project was unloaded, right-click it again, and choose “Edit OldSchoolBeats.csproj”. This will open the .csproj file within Visual Studio. Do a search within the file and look for “AutoMapper.3.1.1” – replace that with “AutoMapper.3.2.0”:
Then right-click the project again and choose “Reload Project” and rebuild the project. The build should complete successfully now. It’s a preview-quirk.
Creating the data-model
From the first part you know, that our database-context is the place where we finally add our DbSets that allow us to query the table data using the database-context. If you take a look at the “Models” folder, you can see there is exactly one file (in my case) “OldSchoolBeatsContext”.Double click the data-context class now and look-out for the TodoItems DbSet entry. Because we won’t use this DbSet it needs to be removed.
Now expand the “DataObjects” folder and delete the file “TodoItems.cs” this is the corresponding model class for the DbSet we have just removed from our data-context. Next thing to do is to remove the file “TodoItemController” from the folder “Controllers”. Simply delete it. One last thing to do is to open the file “WebApiConfig.cs” and comment out the lines within the method “Seed”. This is where we can “seed” initial data into our tables. We will return later here, when we have our model ready. The project should build now without any errors.
Now right-click the folder “Models” and add an new class. Name the class “OldSchoolArtist.cs”. Make it public and let it derive it from “EntityData”. Add the following three automatic-properties:
- Artist – type of string
- YearsArchive – type of string
- RelatedStyles – type of string
The first member will be populated with the artists name like “Grandmaster Flash”. The second member will contain a raw time-span as string like “1980-1990” and the last column will allow us to define related styles like “Electro, OldSchoolRap” and so on.
Please remember that this model is not de-normalized. We are going to do that later on, in the next part.
When you are ready, the file should look something like this:
Now we need to move over to our data-context file “OldSchoolBeatsContext.cs”. Add an additional line to make our entity accessible and ready to be used with our database-context:
To actually be able to access our table using the mobile-services client, we need to add a new controller. The controller will allow us to perform all CRUD-Operations on our table and to set the security level for the controller methods. You don’t want everyone to be able to access your data – right?
This is where the items-templates for Visual Studio created by the mobile-services team come in handy. Right click the controllers folder and choose “Add=>Controller…”
The “Add Scaffold” dialog will pop-up. Choose the entry “Windows Azure Mobile Services Controller” and click “Add”. This will add a controller with all the necessary CRUD REST-Methods we need to work with our OldSchoolArtist entity (Table, later on, when it is generated via Code-First Migrations):
Selecting the template is not the end of the line. We need to supply three more parameter’s to Visual Studio:
- The Model Class: This is our OldSchoolArtist.cs file
- The db-context class: This is our OldSchoolBeatsContext.cs file
- And a name for the controller. Usually the suggestion is ok, and you are good to go
Click on add and the code-generator starts to scaffold-out our new controller, calls OldSchoolArtistController:
- Our controller derives from TableController<T>, this class is an abstract class that derives from TableController, which derives from ApiController that represents the actual Web API controller that I explained in the first part of this series. All the methods called within our controller for the CRUD operations like Query, UpdateAsync, DeleteAsync etc., are protected virtual methods, that means that we can override them within a derived class for example. All the CRUD operations are called by using the DomainManager member of our controller class.
- Within the constructor the controller gets initialized, a parameter of type ControllerContext is injected (more on that in the next part). It contains properties like the ControllerDescriptor which can for example be used to check the name of the current controller and another member HttpConfiguration that allows you to set controller specific message-handlers and formatters for example. If you want to learn more about the ControllerContext class, you can find more information here. On the next line our DbContext is initialized and passed to the “EntityDomainManager” class (this class is used for SQL Server, there’s another class used for Azure Table storage for example) a HttpRequestMessage instance that contains information’s like request-headers, the request-Uri or the request-method (like GET, PUT, POST etc.). The last parameter “Services”. This class is specific to the Azure Mobile services and contains the Log (of type ITraceWriter) or the PushClient for example. In the next part more on that.
- If you take a look at the next 5 methods you will see that all of them begin with a specific request-method prefix. All Methods with the “Get” prefix are called by a get-request and all methods with the “Post” prefix are called via a post-request. The method prefixed with “Patch” is the update method and the method prefixed with “Delete” simply deletes the entry with a specific id (a string) (both of them are http-request-methods as well). You can see that the GetAllOldSchoolArtists() method returns a IQueryable<OldSchoolArtists>. That allows us to query the result-set using LINQ-To-SQL and in case of IQueryable using deferred execution. That means the query against the database is not executed until we actually request the data by calling a ToList() for example on our data-structure. We can filter the outcome of the GetAllOldSchoolArtists() method and receive only the records that we expect from our LINQ-Query. If you are not familiar with deferred execution, I highly suggest this article on MSDN: “”LINQ and Deferred Execution”.
- GetOldSchoolArtist() returns one artist at a time using a return type of SingleResult<T> which returns an IQueryable containing zero or one entities. SingleResult<T> is a member of the System.Web.Http namespace.
- PatchOldSchoolArtist() wants you to pass the ID of the entity to update and the entity that contains the updated data as a Delta<T> object. The Delta<T> class is a change-tracker. It uses some reflection-based magic, first creating a new instance of T, then reading all properties of that instance that can be set (have an setter) and calling the IntersectWith() method on a Dictionary to filter out all properties that cannot be set. Then it simply copies the settable properties from the instance that was passed to the Delta<T> class to the selected entity (the entity that is filtered by the id parameter). All of this magic happens within the UpdateAsync method of our EntityDomainManger instance.
- PostOldSchoolArtist() adds a new record to our database. The return value is of IHttpActionResult that can be a lots of things. In our case it is a CreatedAtRouteNegotiatedContentResult that helps us to return the inserted entity and a http-status of 201 (created), does content-negotiation (for example the client wants JSON to be returned, then the Web API will return a JSON-Serialized version of an OldSchoolArtist). The base for content-negotiation are media-type formatters. If you want to read more about content-negotiation, check out this article: “Content-Negotiation”.
- DeleteAsync() removes the entity with the specified id from the backend.
Firing up your managed service for the first time
Before you actually can do this, we need to ensure that the table behind our model has been created. We will use Entity Framework Code-First migrations to do that. Until now, nothing has happened. To enable code-first migrations, open the NuGet Package Manager Console and type (if you want to learn more about code-first migrations, please check out the first part of this series):
Code-First migrations should be successfully enabled now. To actually make code migrations work in a managed backend, we need to modify our WebApiConfig.cs class that you can find within the “App_Start” folder. This class is responsible for the database-initialization and the configuration of OWIN. We will go into details in the next part of this series. Because the mobile service does not have the rights to drop your tables within the database, we need to disable the database-initializer for now and trigger the migration manually by calling the migrator directly. This is done by commenting-out the line (line 28) the SetInitializer() call and add two lines of code to do that:
Now it should be pretty clear, why we should first enable code-first migrations and then add this two lines of code. It’s because we need the Configuration class that is located in the folder “Migrations” after code-first migrations have been enabled.
Now open that class and set AutomaticMigrationsEnabled to true. This will apply changes to the database automagically after you publish the service to Azure. Otherwise you will get an error message that the current migrations cannot be applied because this flag is set to false.
Now go back to the Package Manager console and type:
This will add our first migration and immediately open the .cs file that contains the migration.
Now hit F5 to actually run the project and to apply the changes to your local database (default is a local-db file). Therefore the first-startup will take a few seconds longer. Your service will be hosted by an instance of IIS-Express. Later when you publish the service, it will actually be hosted in his big brother a full IIS instance.
The service will be fired-up in a new instance of Chrome or IE (depending on your setting within Visual Studio) and this awesome looking site will be shown (you can actually play with that face, by clicking it):
If you go back to Visual Studio and open the “Server Explorer”, you can actually see the local-db file placed under “Data Connections” and that the “OldSchoolArtists” table has been created.
If you go back to the site of your managed service, and you click on “try it out” it will open the help-page for you. Currently you can see there one pre-defined job (which is not really executed currently, but its there and you can trigger it also manually) and all the actions of our OldSchoolArtist-Controller. And take a close look at the method-names. You can see that the GET, POST, PATCH etc. prefixes have been removed. What you actually see are the routes to the different CRUD actions, relative to the root-page, for example http://localhost:9215/api/tables/OldSchoolArtist.
If you click on the first method Get tables/OldSchoolArtist you will see a response sample (JSON formatted) and a green button on the top right that states “try this out” – yes Sir! If you click that button it will open a request-helper dialog, where you actually can test the GET request:
You see that if you actually click on “send” that an empty JSON array is delivered. Well, we have no data in this database (yet). Let’s change that! Press the back-button in your browser and click on the POST-Method. You will see a slightly different view.
Within the “Request Information” section you can see the “Request Body Formats” section and above that section the parameter name “item” . You don’t have to take care about the “_version”, “_createdAt”, “_updatedAt” and “_delted” – columns, those are system columns the framework takes care of. In the next part I will show you how to use those.
Just ignore the “application/x-www-form-urlencoded” error for now and click on t”ry this out”:
Supply values for “artist,yearsArchive,relatedStyles” and leave the rest as-is. Click on “send”.
After successfully posting a new artist, you will see this dialog:
The last line will state that the record was deleted, which is physically not true, it was only “marked” as deleted.
If you now browse back and execute the “GET tables/OldSchoolArtist” request, you will see that the record is still there:
I assume that the “_deleted” system-column is there to mark a record as deleted so that it stays within the table but can be filtered by a query. So far I could not
find any documentation about it.
That’s it so far for part 2. In the next part we go deeper into the guts of the managed backend, and actually create a universal app to use our service. Thank you for reading!