ASP.NET Web APIを使って、WindowsサービスでREST APIを公開する方法を紹介します。
開発環境・動作環境
今回はプロジェクトの都合で、Visual Studio 2010、.NET 4を使いました。
作り方
以下のリンク先の ASP.NET Web API 1を使ったコンソールアプリのチュートリアルを参考にしました。
www.asp.net
VS2010・.NET 4の場合、ASP.NET Web API 2は使えません。
NugetのコンソールからMicrosoft ASP.NET Web Api Self Hostをインストールします。
Install-Package AspNetWebApi.SelfHost
なお、ASP.NET Web API 2の場合は、OWINが使えるようです。
miso-soup3.hateblo.jp
ソースコード
Service.cs
using System.Net.Http.Formatting; using System.ServiceProcess; using System.Web.Http; using System.Web.Http.SelfHost; namespace ApiService { public partial class Service : ServiceBase { private HttpSelfHostServer server = null; public Service() { InitializeComponent(); } protected override void OnStart(string[] args) { this.StartHttpServer(); } protected override void OnStop() { this.StopHttpServer(); } private void StartHttpServer() { HttpSelfHostConfiguration config = new HttpSelfHostConfiguration("http://localhost:8080"); // クエリパラメータでレスポンスのフォーマットを指定できるようにする。 config.Formatters.XmlFormatter.AddQueryStringMapping("format", "xml", "application/xml"); config.Formatters.JsonFormatter.AddQueryStringMapping("format", "json", "application/json"); config.Routes.MapHttpRoute("API Default", "api/{controller}/"); this.server = new HttpSelfHostServer(config); this.server.OpenAsync().Wait(); } private void StopHttpServer() { if (this.server != null) this.server.Dispose(); } } }
PersonController.cs
using System.Web.Http; namespace ApiService { public class PersonController : ApiController { public Person Get(string id) { return new PersonRepository().GetPersonByID(id); } } }
Person.cs
namespace ApiService { public class Person { public string ID { get; set; } public string Name { get; set; } public override string ToString() { return string.Format("ID:[{0}], Name:[{1}]", this.ID, this.Name); } } }
PersonRepository.cs
using System.Collections.Generic; using System.Linq; namespace ApiService { /// <summary> /// 通常は永続化したデータを取得するが、サンプルなのでオンメモリで。 /// </summary> class PersonRepository { private List<Person> personList; public PersonRepository() { this.personList = new List<Person>() { new Person() { ID = "1", Name = "佐藤太郎" }, new Person() { ID = "2", Name = "鈴木太郎" }, new Person() { ID = "3", Name = "田中太郎" }, }; } public Person GetPersonByID(string id) { return this.personList.FirstOrDefault(person => person.ID == id); } } }
動作確認
JSON
1. 以下のリクエストを投げます。
http://localhost:8080/api/person/?id=2&format=json
2. 以下のレスポンスが返されます。
{"ID":"2","Name":"鈴木太郎"}
XML
1. 以下のリクエストを投げます。
http://localhost:8080/api/person/?id=3&format=xml
2. 以下のレスポンスが返されます。
<?xml version="1.0"?> -<Person xmlns="http://schemas.datacontract.org/2004/07/ApiService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ID>3</ID><Name>田中太郎</Name></Person>
はまったこと
- PersonControllerクラスをpublicにする必要があります。internalの場合は404のエラーになります。
- サービスのログオンアカウントに管理者権限がないと、サービスの起動でエラーになります。