.net framework 3.5でスタンドアロンで簡単にウェブサーバを立てる

Wikiエンジンを作るために,IISなどサーバを立てずに,アプリケーションからスタンドアロンウェブサービスを提供するので,ちょっとはまったのでメモ.

方法自体はWCFを使うウェブサービスの作り方そのもの.
HTTPレスポンスのヘッダで Content-Type = "text/html"を指定すること,コンテンツにSystem.IO.Streamを渡すことの2点がポイント.

具体的には,まずサービスを定義する:

using System.ServiceModel;
using System.ServiceModel.Web;
namespace Belka.BookOfNightSky.Accessor
{
    [ServiceContract(Namespace="")]
    public interface IWikiService
    {        
        [OperationContract]        
        [WebGet(UriTemplate="/{wikipage}")]
        System.IO.Stream Get(string wikipage);
    }
}

次にこのインタフェースの実装クラスを書く:

using System.ServiceModel;
using System.ServiceModel.Web;

namespace Belka.BookOfNightSky.Accessor
{
    public class WikiService : IWikiService
    {
        string _xmldecl = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";    
        string _doctype = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";        
        string _content = "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"ja\" lang=\"ja\"><header><title>test page</title></header><body>test page</body></html>";
        #region IWikiService メンバ
        public System.IO.Stream Get(string wikipage)
        {
            // レスポンスヘッダは, WebOperationContext.Current.OutgoingResponse のプロパティを通して設定できる.
            WebOperationContext.Current.OutgoingResponse.ContentType = "text/html; charset=utf-8;";
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(_xmldecl + _doctype + _content));
            return ms;            
        }
        #endregion
    }
}

最後にメインのメソッドでサービスを起動する:

 System.ServiceModel.Web.WebServiceHost _host;
 void Main()
 { 
   _host = new WebServiceHost(typeof(WikiService), new Uri("http://localhost:8000/wiki"));
   _host.Open();   
 }

これで,例えば http://localhost:8000/wiki/some-wiki-page にアクセスすれば,コンテンツがブラウザに表示される.