Host ASP.NET Web API In WPF Application

2012-04-01


WCF Web API is changed to ASP.NET Web API. ASP.NET Web API has the feature of self-host. In Microsoft official site, they have provided two simples ASP.NET Web API self-host samples. However, they are too simple and actually they looks like the "same" one because those 2 samples are Console applications and they use very similar content.

The WPF is more popular for newer Windows Application solutions, so we want to find a sample which is about how to host ASP.NET Web API in a WPF Application. Since we can not find out one currently, so let's do it ourselves.

How to Host ASP.NET Web API In a WPF Application?

First of all, If you have not installed ASP.NET MVC 4 (at present it is still MVC 4 beta), please go to Microsoft ASP.NET website MVC 4 part to download and install it;

After the MVC 4 stuff is installed, we can write the code now.

Note: We are using Visual studio 2010.

1: Open Visual Studio 2010 as Administrator:

(Note: this step is important, the Visual Studio MUST be opened as Administrator because later we need to listen at a particular HTTP address. )

wpfhostwebapi00

Or, if you do not want to open Visual Studio 2010 as Administrator, you must use Netsh.exe to give your current Windows user account permissions to reserve the URL first:

netsh http add urlacl url=http://+:8080/ user=machine\username 

(check Microsoft sample here)

2: Create a WPF application, We give a project name WpfHostWebApiDemo, please make sure .NET Framework 4 is selected:

(for avoiding the build errors which will be mentioned in the step 7, maybe you can read step 7 first, if you don't want to do the target framework changing, you are still OK but you will have to following everything descripted in step 7 later)

wpfhostwebapi01

3: Install ASP.NET Web API Self Host package:

We will use NuGet Package Manager to install ASP.NET Web API Self Host package. Right click the project name in Visual Studio 2010, and choose "Manage NuGet Packages…", If you can not see this item, it means you have not installed NuGet Package Manager for Visual Studio 2010, Please go to NuGet project site to get help information to download and install it.

wpfhostwebapi02

_About NuGet:
_NuGet is a Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects that use the .NET Framework. When you add a library or tool, NuGet copies files to your solution and automatically makes whatever changes are needed in your project, such as adding references and changing your app.config or web.config file. When you remove a library, NuGet removes files and reverses whatever changes it made in your project so that no clutter is left.

When you open the Manager NuGet Packages Windows, input "webapi selfhost" in the top right search box, The Manager can search automatically for you, You will see "ASP.NET Web API Self Host (Beta)" (Currently it is still in Beta stage) and you can click Install Button.

wpfhostwebapi03

After clicking the Install button, the installation process begins:

wpfhostwebapi04 wpfhostwebapi05

After the installation process is complete, please click the Close button to close NuGet Package Manager.

Now you can see some information in the output windows of Visual Studio 2010:
wpfhostwebapi06

Also, you should see there are new references have been added into current project:
wpfhostwebapi07

Now we are ready to start our Web API in the existing project.

4: In the current project, Add a folder and name it as Models, and add a Model class and name it as ItemModel:

namespace WpfHostWebApiDemo.Models
{
    public class ItemModel
    {
        public int ItemID { get; set; }
        public string ItemName { get; set; }
        public double ItemValue { get; set; }
    }
}

5: Add a new folder named Controllers, in this folder, add a new Item, specify the template to Web API Controller Class in Web category. Give the name ItemController

wpfhostwebapi08

Remove all generated code and add the following code into ItemController class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using WpfHostWebApiDemo.Models;

namespace WpfHostWebApiDemo.Controllers.Controllers
{
    public class ItemController : ApiController
    {
        // GET /api/<controller>
        public IEnumerable<ItemModel> Get()
        {
            return new List<ItemModel> 
            {
                new ItemModel() { ItemID = 1, ItemName = "Item1", ItemValue = 100 },
            };
        }
    }
}

6: Host service:

Add the windows loaded event in MainWindow, and add host service code, All MainWindow.xaml,cs file code is like the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Web.Http.SelfHost;
using System.Web.Http;

namespace WpfHostWebApiDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var config = new HttpSelfHostConfiguration("http://localhost:5477");

            config.Routes.MapHttpRoute(
                "API Default", "api/{controller}/{id}",
                new { id = RouteParameter.Optional });

            using (HttpSelfHostServer server = new HttpSelfHostServer(config))
            {
                server.OpenAsync().Wait();

                MessageBox.Show("Web API service started.");
            }
        }
    }
}

In the above code, we listen to localhost:5477, you can change the port number to any port number you like.

7: Compile and Build project:

Now we build the project, we might see at least 5 error messages here:

The type or namespace name 'ApiController' could not be found (are you missing a using directive or an assembly reference?)

The type or namespace name 'SelfHost' does not exist in the namespace 'System.Web.Http' (are you missing an assembly reference?)

The type or namespace name 'HttpSelfHostConfiguration' could not be found (are you missing a using directive or an assembly reference?)

The type or namespace name 'HttpSelfHostServer' could not be found (are you missing a using directive or an assembly reference?)

The type or namespace name 'HttpSelfHostServer' could not be found (are you missing a using directive or an assembly reference?)

_wpfhostwebapi09

The reason is the current WPF project is based on the target framework ASP.NET Framework 4 Client Profile, which misses some libraries. So just right click the project name in Visual Studio 2010 and select property, and change the target framework to ASP.NET Framework 4.

wpfhostwebapi10

After you changed the target framework to .NET Framework 4, Visual Studio 2010 will give you a message that the project need to be closed and re-open, but looks seems the Visual Studio 2010 can not re-load the project automatically, so here you should close Visual Studio manually first, and open Visual Studio 2010 as Administrator again, and load the demo project.

(Note: for avoid to re-open Visual Studio, you’d better change Target framework in step 2)

Now let us rebuild the application, we see the above 5 error messages are gone, but we get the following new errors:

The type 'System.Web.Routing.RouteCollection' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'._

The type 'System.Web.Routing.Route' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'._

The reason is that we still miss a dll file, let’s add reference to System.Web, the version is 4.0

wpfhostwebapi11

Now rebuild the project again. the build should be OK now!

8: Run the Web API Service:

Click Ctrl + F5, you will see the service started message which we added in code.

wpfhostwebapi12

Open web browser and input the URL address:

localhost:5477/api/item

You will see the service content as XML format on the web page:

wpfhostwebapi13

Now we know the Web API service is working! You can create a client to consume the service now.