Self-Host ASP.NET Web API 1 (C#)
by Mike Wasson
ASP.NET Web API does not require IIS. You can self-host a web API in your own host process. This tutorial shows how to host a web API inside a console application.
New applications should use OWIN to self-host Web API. See Use OWIN to Self-Host ASP.NET Web API 2.
Software versions used in the tutorial
- Web API 1
- Visual Studio 2012
Create the Console Application Project
Start Visual Studio and select New Project from the Start page. Or, from the File menu, select New and then Project.
In the Templates pane, select Installed Templates and expand the Visual C# node. Under Visual C#, select Windows. In the list of project templates, select Console Application. Name the project “SelfHost” and click OK.
Set the Target Framework (Visual Studio 2010)
If you are using Visual Studio 2010, change the target framework to .NET Framework 4.0. (By default, the project template targets the .Net Framework Client Profile.)
In Solution Explorer, right-click the project and select Properties. In the Target framework dropdown list, change the target framework to .NET Framework 4.0. When prompted to apply the change, click Yes.
Install NuGet Package Manager
The NuGet Package Manager is the easiest way to add the Web API assemblies to a non-ASP.NET project.
To check if NuGet Package Manager is installed, click the Tools menu in Visual Studio. If you see a menu item called Library Package Manager, then you have NuGet Package Manager.
To install NuGet Package Manager:
- Start Visual Studio.
- From the Tools menu, select Extensions and Updates.
- In the Extensions and Updates dialog, select Online.
- If you don’t see “NuGet Package Manager”, type “nuget package manager” in the search box.
- Select the NuGet Package Manager and click Download.
- After the download completes, you will be prompted to install.
- After the installation completes, you might be prompted to restart Visual Studio.
Add the Web API NuGet Package
After NuGet Package Manager is installed, add the Web API Self-Host package to your project.
- From the Tools menu, select Library Package Manager. Note: If do you not see this menu item, make sure that NuGet Package Manager installed correctly.
- Select Manage NuGet Packages for Solution…
- In the Manage NugGet Packages dialog, select Online.
- In the search box, type “Microsoft.AspNet.WebApi.SelfHost”.
- Select the ASP.NET Web API Self Host package and click Install.
- After the package installs, click Close to close the dialog.
[!NOTE] Make sure to install the package named Microsoft.AspNet.WebApi.SelfHost, not AspNetWebApi.SelfHost.
Create the Model and Controller
This tutorial uses the same model and controller classes as the Getting Started tutorial.
Add a public class named Product
.
[!code-csharpMain]
1: namespace SelfHost
2: {
3: public class Product
4: {
5: public int Id { get; set; }
6: public string Name { get; set; }
7: public string Category { get; set; }
8: public decimal Price { get; set; }
9: }
10: }
Add a public class named ProductsController
. Derive this class from System.Web.Http.ApiController.
[!code-csharpMain]
1: namespace SelfHost
2: {
3: using System;
4: using System.Collections.Generic;
5: using System.Linq;
6: using System.Net;
7: using System.Web.Http;
8:
9: public class ProductsController : ApiController
10: {
11: Product[] products = new Product[]
12: {
13: new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
14: new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
15: new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
16: };
17:
18: public IEnumerable<Product> GetAllProducts()
19: {
20: return products;
21: }
22:
23: public Product GetProductById(int id)
24: {
25: var product = products.FirstOrDefault((p) => p.Id == id);
26: if (product == null)
27: {
28: throw new HttpResponseException(HttpStatusCode.NotFound);
29: }
30: return product;
31: }
32:
33: public IEnumerable<Product> GetProductsByCategory(string category)
34: {
35: return products.Where(p => string.Equals(p.Category, category,
36: StringComparison.OrdinalIgnoreCase));
37: }
38: }
39: }
For more information about the code in this controller, see the Getting Started tutorial. This controller defines three GET actions:
URI | Description |
---|---|
/api/products | Get a list of all products. |
/api/products/id | Get a product by ID. |
/api/products/?category=category | Get a list of products by category. |
Host the Web API
Open the file Program.cs and add the following using statements:
[!code-csharpMain]
1: using System.Web.Http;
2: using System.Web.Http.SelfHost;
Add the following code to the Program class.
[!code-csharpMain]
1: var config = new HttpSelfHostConfiguration("http://localhost:8080");
2:
3: config.Routes.MapHttpRoute(
4: "API Default", "api/{controller}/{id}",
5: new { id = RouteParameter.Optional });
6:
7: using (HttpSelfHostServer server = new HttpSelfHostServer(config))
8: {
9: server.OpenAsync().Wait();
10: Console.WriteLine("Press Enter to quit.");
11: Console.ReadLine();
12: }
(Optional) Add an HTTP URL Namespace Reservation
This application listens to http://localhost:8080/
. By default, listening at a particular HTTP address requires administrator privileges. When you run the tutorial, therefore, you may get this error: “HTTP could not register URL http://+:8080/” There are two ways to avoid this error:
- Run Visual Studio with elevated administrator permissions, or
- Use Netsh.exe to give your account permissions to reserve the URL.
To use Netsh.exe, open a command prompt with administrator privileges and enter the following command:following command:
[!code-consoleMain]
1: netsh http add urlacl url=http://+:8080/ user=machine\username
where *machineis your user account.
When you are finished self-hosting, be sure to delete the reservation:
[!code-consoleMain]
1: netsh http delete urlacl url=http://+:8080/
Call the Web API from a Client Application (C#)
Let’s write a simple console application that calls the web API.
Add a new console application project to the solution:
- In Solution Explorer, right-click the solution and select Add New Project.
- Create a new console application named “ClientApp”.
Use NuGet Package Manager to add the ASP.NET Web API Core Libraries package:
- From the Tools menu, select Library Package Manager.
- Select Manage NuGet Packages for Solution…
- In the Manage NuGet Packages dialog, select Online.
- In the search box, type “Microsoft.AspNet.WebApi.Client”.
- Select the Microsoft ASP.NET Web API Client Libraries package and click Install.
Add a reference in ClientApp to the SelfHost project:
- In Solution Explorer, right-click the ClientApp project.
- Select Add Reference.
- In the Reference Manager dialog, under Solution, select Projects.
- Select the SelfHost project.
- Click OK.
Open the Client/Program.cs file. Add the following using statement:
[!code-csharpMain]
1: using System.Net.Http;
Add a static HttpClient instance:
[!code-csharpMain]
1: namespace Client
2: {
3: class Program
4: {
5: static HttpClient client = new HttpClient();
6: }
7: }
Add the following methods to list all products, list a product by ID, and list products by category.
[!code-csharpMain]
1: static void ListAllProducts()
2: {
3: HttpResponseMessage resp = client.GetAsync("api/products").Result;
4: resp.EnsureSuccessStatusCode();
5:
6: var products = resp.Content.ReadAsAsync<IEnumerable<SelfHost.Product>>().Result;
7: foreach (var p in products)
8: {
9: Console.WriteLine("{0} {1} {2} ({3})", p.Id, p.Name, p.Price, p.Category);
10: }
11: }
12:
13: static void ListProduct(int id)
14: {
15: var resp = client.GetAsync(string.Format("api/products/{0}", id)).Result;
16: resp.EnsureSuccessStatusCode();
17:
18: var product = resp.Content.ReadAsAsync<SelfHost.Product>().Result;
19: Console.WriteLine("ID {0}: {1}", id, product.Name);
20: }
21:
22: static void ListProducts(string category)
23: {
24: Console.WriteLine("Products in '{0}':", category);
25:
26: string query = string.Format("api/products?category={0}", category);
27:
28: var resp = client.GetAsync(query).Result;
29: resp.EnsureSuccessStatusCode();
30:
31: var products = resp.Content.ReadAsAsync<IEnumerable<SelfHost.Product>>().Result;
32: foreach (var product in products)
33: {
34: Console.WriteLine(product.Name);
35: }
36: }
Each of these methods follows the same pattern:
- Call HttpClient.GetAsync to send a GET request to the appropriate URI.
- Call HttpResponseMessage.EnsureSuccessStatusCode. This method throws an exception if the HTTP response status is an error code.
- Call ReadAsAsync<T> to deserialize a CLR type from the HTTP response. This method is an extension method, defined in System.Net.Http.HttpContentExtensions.
The GetAsync and ReadAsAsync methods are both asynchronous. They return Task objects that represent the asynchronous operation. Getting the Result property blocks the thread until the operation completes.
For more information about using HttpClient, including how to make non-blocking calls, see Calling a Web API From a .NET Client.
Before calling these methods, set the BaseAddress property on the HttpClient instance to “http://localhost:8080
”. For example:
[!code-csharpMain]
1: static void Main(string[] args)
2: {
3: client.BaseAddress = new Uri("http://localhost:8080");
4:
5: ListAllProducts();
6: ListProduct(1);
7: ListProducts("toys");
8:
9: Console.WriteLine("Press Enter to quit.");
10: Console.ReadLine();
11: }
This should output the following. (Remember to run the SelfHost application first.)
[!code-consoleMain]
1: 1 Tomato Soup 1.0 (Groceries)
2: 2 Yo-yo 3.75 (Toys)
3: 3 Hammer 16.99 (Hardware)
4: ID 1: Tomato Soup
5: Products in 'toys':
6: Yo-yo
7: Press Enter to quit.
|