ここではあなたはNugetをインストールしており、Visual Studio 2010を使って いることを前提として話を進めています。 しかしこれと同等なことをMono(Version 2.10.2以降)とMonoDevelopを使っても できます。 NancyとNancyのASP.NET Hostingを使った"hello world"アプリケーション作成に 至るまでの過程を以下に示します。
-
新しい"ASP.NET Empty Web Application"を作成
-
NancyのためのASP.NET Hostをインストール
Install-package Nancy.Hosting.Aspnet
(これはNuGetでNancyをインストールし、Nancyがどんなリクエストにも 対応できるようにweb.configを更新します。)
-
Nancyモジュールを加える。これは標準のC#クラスであり、Webアプリケーション のルートURLのルートハンドラを定義する。
-
コンパイルと実行
// Nancyモジュール public class HelloModule : NancyModule { public HelloModule() { // ルートURLのルートハンドラを定義する。 Get["/"] = parameters => "Hello World"; } }
あなたはコンソールアプリケーションをNancyのホストとすることもできます。
Nancy.Hosting.Self
パッケージをNuGetでインストールし、以下のコードを使えば
実現できます。
using System;
using Nancy.Hosting.Self;
public class SelfHostingNancySample
{
public static void Main()
{
// ルートURLを引数にしてNancyHostインスタンスを作成する。
var nancyHost = new NancyHost(
new Uri("http://localhost:2000")
);
// ホストを起動する。
nancyHost.Start();
// ホストを停止させないように入力待ち状態にする。
Console.ReadLine();
// ホストを停止する。
nancyHost.Stop();
}
}
Windowsにおいて、"Access Denied"というメッセージのHttpListenerException を投げてくるかもしれません。これを解決するにはそのURLをACLに加える必要が あります。
netsh http add urlacl url=http://+:2000/ user=DOMAIN\username
DOMAIN\username
の部分は各自の「コンピュータ名+''+ユーザー名」に
置き換えてください。
この操作を取り消すには以下のコマンドを実行します。
netsh http delete urlacl url=http://+:2000/
また、このURLをほかのコンピュータからアクセスできるようにするには そのポートを解放する必要があります。
モジュールはあなたがアプリケーションの振る舞いを定義することを 許可することのほかにもより多くのことをします。 モジュールは現在のリクエスト、そのリクエストが処理されているコンテキスト、 レスポンスに対するヘルパー、ビューのレンダリング、などの情報へのアクセスを あなたに提供します。 モジュールはNancyModuleクラスを継承することによって生成されます。 モジュールは実行時のアプリケーションドメイン内ならどこにでも宣言することができます。 これはたとえば外部(external)アセンブリ内に定義されたモジュールも含まれることを意味します。
モジュールの特徴の1つはモジュールパスを定義することである。 Nancyは共通となる下位のルートパスをうまくグルーピングすることが できる。
public class ResourceModule : NancyModule
{
public ResourceModule() : base("/products")
{
// Getリクエストの/products/listへのルートをキャプチャする
Get["/list"] = parameters => {
return "The list of products";
};
}
}
ルートはモジュールのコンストラクタに定義されます。
Nancyでルートを定義するには、あなたはMethod
+Pattern
+
Action
+(optional)Condition
と記述する必要があります。
public class ProductsModule : NancyModule
{
public ProductsModule
{
//`Method`+`Pattern`+`Action`
Get["/products/{id}"] = _ =>
{
// do something
};
}
}
メソッドはリソースにアクセスするために使われるHTTPメソッドです。
NancyはDELETE
, GET
, HEAD
, OPTIONS
, POST
, PUT
, PATCH
のメソッドをサポートしています。
HEAD
リクエストはGETリクエストが宣言されたすべてのルートのために
自動的に使われます。
ルートには常にアプリケーションの相対URLを含むパターンが必要です。 パターンのシンタックスはカスタマイズ可能だが、Nancyは以下のような 組み合わせをキャプチャするデフォルトの実装がある。
- Literal segments -(10,000)-
/some/literal/segments
: - Capture segments -(1,000)-
/{name}
: - Capture segments (optional) -(1,000)-
/{name?}
: - Capture segments (optional/default) -(1,000)-
/{name?unnamed}/
: - RegEx segment -(1,000)-
/(?<age>[\d]{1,2})
: - Greedy segment -(0)-
/{name*}
: - Greedy RegEx segment -(100)-
^(?<name>[a-z]{3,10}(?:/{1})(?<action>[a-z]{5,10}))$
:
-(...)-
内の数値はスコアです。
このスコアは以下のような複数のパターンにマッチしたときに使われます。
public class HomeModule : NancyModule
{
public HomeModule()
{
Get["/{category}"] = _ =>
{
return "My category is " + _.category;
}
Get["/sayhello"] = _ =>
{
return "Hello from Nancy";
}
}
}
最初のルートは2.Capture Segments、そして2つ目のルートは1.Literal Segment。 この場合、スコアの高いほうが優先されます。よって2つ目のルートが選ばれます。
アクションはルートにマッチしたリクエストが発行(実施)されたときの振る舞いです。
それはFunc<dynamic, dynamic>
型のラムダ式によって表現されます。
そのdynamicな入力値(第1引数にあたる)はDynamicDictionary
という型である。
この型はNancyの中に定義されています。
The response can be any model and the final result will be determined by Content Negotiation. However, if it is of the type Response then content negotiation will be ignored and the response will be sent straight back to the host.
Response
オブジェクトはいろんなimplicit cast operatorを宣言しています。
それはアクションになることが可能であり、Response
オブジェクトの代わりに
なります。代わりになりえる型は以下のうちのどれかです。
int
: レスポンスのHTTPステータスコードとして扱われます。HttpStatusCode
: HTTPステータスコードの列挙型。string
: レスポンスのbodyとして扱われます。Action<Stream>
: レスポンスのストリームに書き込む関数オブジェクト。
https://github.com/NancyFx/Nancy/wiki/Defining-routes
public class SampleModule : NancyModule { public SampleModule() { Get["/"] = parameters => { return View["wwwroot/products.html"]; }; Post["/login", (ctx) => ctx.Request.Form.remember] = _ => { return "Handling code when remember is true!"; };
Post["/login", (ctx) => !ctx.Request.Form.remember] = _ =>
{
return "Handling code when remember is false!";
};
}
}
using System;
using Nancy;
using Nancy.Hosting.Self;
public class A
{
public static void Main()
{
var nancyHost = new NancyHost(new Uri("http://localhost:2000"));
nancyHost.Start();
Console.ReadLine();
nancyHost.Stop();
}
}
public class SampleModule : NancyModule
{
public SampleModule()
{
Get["/hello"] = parameters => {
return "Hello!";
};
}
}
var a = View["wwwroot/products.html", this]; // Nancy.Responses.Negotiation.Negotiator return a.GetType().ToString();
// Nancy.NancyModule+ViewRenderer return View.GetType().ToString();
/// <summary>
/// Renders a view from inside a route handler.
/// </summary>
/// <value>A <see cref="ViewRenderer"/> instance that is used to determin which view that should be rendered.</value>
public ViewRenderer View
{
get { return new ViewRenderer(this); }
}
Nancyはlightweight、low-ceremony、 .NetとMono上のサービスがもととなるHTTPで作られた フレームワークです。
ベースとなるルートを設定することも可能。
//Getリクエストの'/products/list'にあたる。 public ResourceModule() : base("/products"){ Get["/list"] = ... }
ルートはモジュールのコンストラクタ内に定義されます。 In order to define a route in Nancy, you need to specify a Method + Pattern + Action + (optional) Condition.
public class DynamicDictionary : DynamicObject, IEquatable, IHideObjectMembers, IEnumerable, IDictionary<string, object>
Allows to host Nancy server inside any application - console or windows service.
NancyHostは内部でSystem.Net.HttpListener
を使用している。
要するに、実行させるためには.Net 4.0 Profileをフルに必要とする(Client Profileではなく)。
Start
はリクエストを受け付けるためのスレッドを起動させ、そして、それらのリクエストを処理するだろう。
すべてのプロセスはシングルスレッド内で処理される。セルフホスティングはプロダクトのために作られているわけではない。
むしろ、開発サーバー向きである。
NancyHost needs SerializableAttribute
in order to be used from another appdomain under mono.
Working with AppDomains is necessary if you want to unload the dependencies that come with NancyHost.
指定されたbaseUris
のためのNancyHost
クラスの新しいインスタンスを初期化する。
デフォルトの設定を使用する。
`baseUris`: The `Uri`s that the host will listen to.
指定されたbaseUris
のためのNancyHost
クラスの新しいインスタンスを初期化する。
指定されたconfiguration
の設定を使用する。
`baseUris`: The `Uri`s that the host will listen to.
`configuration`: Configuration to use
指定されたbaseUris
のためのNancyHost
クラスの新しいインスタンスを初期化する。
using the provided bootstrapper
.
デフォルトの設定を使用する。
`bootstrapper`: The bootstrapper that should be used to handle the request.
`baseUris`: The `Uri`s that the host will listen to.
public NancyHost(INancyBootstrapper bootstrapper, HostConfiguration configuration, params Uri[] baseUris)
指定されたbaseUris
のためのNancyHost
クラスの新しいインスタンスを初期化する。
using the provided bootstrapper
.
指定されたconfiguration
の設定を使用する。
`bootstrapper`:The bootstrapper that should be used to handle the request.
`configuration`: Configuration to use
`baseUris`: The `Uri`s that the host will listen to.
指定されたbaseUris
のためのNancyHost
クラスの新しいインスタンスを初期化する。
using the provided bootstrapper
.
デフォルトの設定を使用する。
`baseUri`:The `Uri` that the host will listen to.
`bootstrapper`:The bootstrapper that should be used to handle the request.
指定されたbaseUri
のためのNancyHost
クラスの新しいインスタンスを初期化する。
using the provided bootstrapper
.
指定されたconfiguration
の設定を使用する。
`baseUri`: The `Uri` that the host will listen to.
`bootstrapper`: The bootstrapper that should be used to handle the request.
`configuration`: Configuration to use
もし、ホストが実行中なら停止する。
与えられた設定(HostConfiguration)でリクエストの受け付けを開始する。
リクエストの受け付けを止める。
Host configuration for the self host
Gets or sets a property that determines if localhost uris are rewritten to htp://+:port/ style uris to allow for listening on all ports, but requiring either a url reservation, or admin access Defaults to true.
Configuration around automatically creating url reservations
Gets or sets a property that determines if Transfer-Encoding: Chunked is allowed for the response instead of Content-Length (default: true).
Gets or sets a property that provides a callback to be called if there's an unhandled exception in the self host. Note: this will not be called for normal nancy Exceptions that are handled by the Nancy handlers. Defaults to writing to debug out.
Gets or sets a property that determines whether client certificates are enabled or not. When set to true the self host will request a client certificate if the request is running over SSL. Defaults to false.
{
this.UrlReservations = new UrlReservations();
this.UnhandledExceptionCallback = e =>
{
var message = string.Format("---\n{0}\n---\n", e);
Debug.Write(message);
};
}