Using the ASP.NET Web API With ServiceStack OrmLite and MVC

The ASP.NET Web API http://www.asp.net/web-api is a new framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework. ASP.NET MVC 4 includes the Web API, and for Visual Studio 11, it is already included and does not need to be installed.

In ASP.NET Web API, a controller is a class that handles HTTP requests. The public methods of the controller are called action methods or simply actions. When the Web API framework receives a request, it routes the request to an action.

To determine which action to invoke, the framework uses a routing table. If you are hosting Web API from ASP.NET, the routing table is created in the Global.asax file. By default when you use Visual Studio to create a new Web API project, the project template creates a default route for you.

If this all sounds a lot like ASP.NET MVC, it's because it is. Once a matching route is found, Web API selects the controller and the action.

To find the controller, Web API adds "Controller" to the value of the {controller} variable. To find the action, Web API looks at the HTTP method, and then looks for an action whose name begins with that HTTP method name.   Other placeholder variables in the route template, such as {id}, are mapped to action parameters, just as with ASP.NET MVC.

ASP.NET Web API has a pipeline for processing HTTP messages on both the client and server. The client and server sides are designed to be symmetrical but independent; you can use each half by itself. Both sides are built on some common objects:

HttpRequestMessage represents the HTTP request.
HttpResponseMessage represents the HTTP response.
HttpMessageHandler objects process the request and response.

This provides for a nice, compact, and efficient way of transmitting Request and Response objects that contain all the data for the payload involved.

You can also write custom message handlers, which would derive from the System.Net.Http.DelegatingHandler class.

In ASP.NET Web API, a media formatter is an object that can:

Read CLR objects from an HTTP message body
Write CLR objects into an HTTP message body
Web API provides media-type formatters for both JSON and XML. The framework inserts these formatters into the pipeline by default. Clients can request either JSON or XML in the Accept header of the HTTP request.

The Web API can either be self-hosted, or run from within an ASP.NET web application. Although ASP.NET Web API is packaged with ASP.NET MVC, it is easy to add Web API to a traditional ASP.NET Web Forms application.

ASP.NET Web API is also designed so that you can use your choice of tracing/logging library, and you can inject dependencies into your ASP.NET Web API controller using the Web API dependency resolver.

To put this demo together, I started out with the "Contacts" Demo provided by Microsoft, and added a real backing store via SQL Server and the ServiceStack ORMLite infrastructure. The infrastructure begins life in the Application_Start event of the Global class:

  public static OrmLiteConnectionFactory DbFactory;
         protected void Application_Start()
        {
            DbFactory = new OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString, SqlServerOrmLiteDialectProvider.Instance);

            OrmLiteConfig.DialectProvider = new SqlServerOrmLiteDialectProvider();
             using (IDbConnection dbConn = DbFactory.OpenDbConnection())
             {
                 using (IDbCommand dbCmd = dbConn.CreateCommand())
                {
                    const bool overwrite = false;
                    dbCmd.CreateTables(overwrite, typeof (Contact));
                }
            }
            RegisterApis(GlobalConfiguration.Configuration);
        }

The above code creates a static instance of the OrmLiteConnectionFactory, and then creates the Contacts SQL Server table directly from the Contact class. This only happens once, the overwrite bool parameter will not overwrite if the table already exists. It then goes on to handle registering the APIs.

My Contact class looks like the following:

using System;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using ServiceStack.DataAnnotations;
using ServiceStack.DesignPatterns.Model;

namespace ContactManager.Models
{
    [Alias("Contacts")]
    public class Contact :IHasId<Int32>
    {
         [PrimaryKey]
         [AutoIncrement]
         public int Id { get; set; }
      
         [StringLength(350)]
         public string Name { get; set; }

         [StringLength(350)]
        public string Address { get; set; }

         [StringLength(35)]
        public string City { get; set; }

         [StringLength(25)]
        public string State { get; set; }

         [StringLength(12)]
        public string Zip { get; set; }

         [StringLength(350)]
        public string Email { get; set; }

         [StringLength(350)]
        public string Twitter { get; set; }

         [StringLength(350)]
        public string Self
        {
            get { return string.Format(CultureInfo.CurrentCulture, "contact/{0}", this.Id); }
            set { }
        }
    }
}

Note that I am using DataAnnotations attributes to set up the table schema.  And here is the ContactRepository that does all the "heavy lifting":

using ServiceStack.OrmLite;

namespace ContactManager.Models
{
    using System.Collections.Generic;
    using System.Linq;

    public class ContactRepository : IContactRepository
    {
         public ContactRepository()
        {

        }

         public void Update(Contact updatedContact)
        {
            WebApiApplication.DbFactory.Exec(dbCmd => dbCmd.Update(updatedContact));
         }

        public Contact Get(int id)
        {
            return WebApiApplication.DbFactory.Exec(dbCmd => dbCmd.GetById<Contact>(id));
        }

         public List<Contact> GetAll()
        {
            using (IDbConnection dbConn = WebApiApplication.DbFactory.OpenDbConnection())
             {
                  using (IDbCommand dbCmd = dbConn.CreateCommand())
                 {
                      using (IDbTransaction dbTrans = dbCmd.BeginTransaction())
                      {
                          return dbCmd.Select<Contact>();
                     }
                 }
             }

        }

        public void Post(Contact contact)
        {
            WebApiApplication.DbFactory.Exec(dbCmd => dbCmd.Save(contact));
        }

        public void Delete(int id)
        {
            WebApiApplication.DbFactory.Exec(dbCmd => dbCmd.DeleteById<Contact>(id));
        }
    }
}

This is pretty much all it takes to wire in ServiceStack ORMLite to any application, either MVC or Web API. When you download the Demo, you'll need to create a new SQL Server Database "TEST" first. The application itself takes care of creating the table from the model. All of the ServiceStack assemblies needed are located in the /Libs folder. ServiceStack ORMLite is lightning fast (just behind Dapper-Dot-Net, the performance speed champion) and it's friendly extension methods make it extra easy to perform the kinds of CRUD operations you need.

You can download the Visual Studio 2010 solution and accompanying assemblies here.


By Peter Bromberg   Popularity  (13007 Views)