前回に.NET Frameworkで使える軽量WebフレームワークNancyを、本当にプラットフォームをまたいで使えるかためした。前回はコードに手をつけなかたので、今回はそこを。前回作成したプロジェクトをいじっていくことにする。
SinatraインスパイアのWebフレームワークNancyを試す
下記がデフォルトのIndexModule.csというコードファイル。これがクライアントからのリクエストの処理を司っている。ラムダ式でガリガリ処理を書いていく。
上記はルートにアクセスすると、index.sshtmlにテンプレートを施した結果を返すようになっている。もうちょいシンプルにするためにテンプレートを抜いてただの文字列だけ返すようにして、パスやクエリ、フォームからの送信値を変数として扱う方法の例をまず。
一番上から。/welcome/Johnにアクセスすると"Welcome, John"が表示される。
その下。/bye?name=Johnにアクセスすると"Bye, John"が表示される。
三つ目。/helloにアクセスするとフォームが表示される。フォームに入れた文字列はPostされるようになっている。"John"をPostすると、その下のPost["/hello"]に入れたラムダ式が実行され、結果として"Hello, John"が返ってくる。
上記の例は文字列を返しているが、デフォルトではHTTPヘッダのコンテンツタイプはtext/htmlになっているので、実はヘッダとコンテンツの間に矛盾が生じている。ただの文字列を返したいとき、正しくは下記のように。
さらに使いそうな処理パターンを加えてみる。文字列やHTMLだけでなくJSONを返したいときもあるだろう。JSN文字列を作りつつ、ヘッダのコンテンツタイプをいじる。

返すコンテンツが文字列だけとは限らない。Postされた画像を加工して返すとか、データベースに入れられた画像のバイナリデータを返すことも考えられる。

認証エラーとかコンテンツが見つからないときはエラーコードを与えたいこともある。

HTML以外のレスポンスも、HTTPのヘッダをいじるメソッドを実行することで返せる。非常にシンプル。
マイクロフレームワークとか呼ばれるものの便利な点は、HTTPをそれなりわかっていれば、やりたいことはわりとパッとできるところにあると思う。それを考えると逆に、C#でNancyを使いつつHTTPを学んでみるのも一考。
とりあえず今回書いたコードの全体をまとめたものも載せておく。
SinatraインスパイアのWebフレームワークNancyを試す
下記がデフォルトのIndexModule.csというコードファイル。これがクライアントからのリクエストの処理を司っている。ラムダ式でガリガリ処理を書いていく。
namespace NancySelf
{
using Nancy;
public class IndexModule : NancyModule
{
public IndexModule()
{
Get["/"] = parameters =>
{
return View["index"];
};
}
}
}
上記はルートにアクセスすると、index.sshtmlにテンプレートを施した結果を返すようになっている。もうちょいシンプルにするためにテンプレートを抜いてただの文字列だけ返すようにして、パスやクエリ、フォームからの送信値を変数として扱う方法の例をまず。
namespace NancySelf
{
using Nancy;
public class IndexModule : NancyModule
{
public IndexModule()
{
// url
Get["/welcome/{name}"] = parameters =>
{
return "Welcome, " + parameters.name;
};
// query
Get["/bye"] = parameters =>
{
return "Bye, " + Request.Query.name;
};
// post form
Get["/hello"] = parameters =>
{
return View["hello"];
};
Post["/hello"] = parameters =>
{
return "Hello, " + Request.Form.name;
};
Get["/"] = parameters =>
{
return View["index"];
};
}
}
}
一番上から。/welcome/Johnにアクセスすると"Welcome, John"が表示される。
その下。/bye?name=Johnにアクセスすると"Bye, John"が表示される。
三つ目。/helloにアクセスするとフォームが表示される。フォームに入れた文字列はPostされるようになっている。"John"をPostすると、その下のPost["/hello"]に入れたラムダ式が実行され、結果として"Hello, John"が返ってくる。
上記の例は文字列を返しているが、デフォルトではHTTPヘッダのコンテンツタイプはtext/htmlになっているので、実はヘッダとコンテンツの間に矛盾が生じている。ただの文字列を返したいとき、正しくは下記のように。
Get["/welcome/{name}"] = parameters =>
{
var response = (Response)("Welcome, " + parameters.name);
response.ContentType = "text/plain";
return response;
};
さらに使いそうな処理パターンを加えてみる。文字列やHTMLだけでなくJSONを返したいときもあるだろう。JSN文字列を作りつつ、ヘッダのコンテンツタイプをいじる。
Get["/hey"] = parameters =>
{
var dict = new Dictionary<string, string>();
dict.Add("name", "John");
var jss = new JavaScriptSerializer();
var jsonStr = jss.Serialize(dict);
var response = (Response)jsonStr;
response.ContentType = "application/json";
return response;
};

返すコンテンツが文字列だけとは限らない。Postされた画像を加工して返すとか、データベースに入れられた画像のバイナリデータを返すことも考えられる。
Get["/image"] = parameters =>
{
byte[] data = File.ReadAllBytes("Content/nancy-logo.png");
var response = new Response();
response.ContentType = "image/png";
response.Contents = s => s.Write(data, 0, data.Length);
return response;
};

認証エラーとかコンテンツが見つからないときはエラーコードを与えたいこともある。
Get["/error404"] = parameters =>
{
var response = (Response)"404ERROR";
response.WithStatusCode(404);
return response;
};

HTML以外のレスポンスも、HTTPのヘッダをいじるメソッドを実行することで返せる。非常にシンプル。
マイクロフレームワークとか呼ばれるものの便利な点は、HTTPをそれなりわかっていれば、やりたいことはわりとパッとできるところにあると思う。それを考えると逆に、C#でNancyを使いつつHTTPを学んでみるのも一考。
とりあえず今回書いたコードの全体をまとめたものも載せておく。
namespace NancySelf
{
using System.Collections.Generic;
using System.IO;
using System.Web.Script.Serialization;
using Nancy;
public class IndexModule : NancyModule
{
public IndexModule()
{
// url
Get["/welcome/{name}"] = parameters =>
{
return "Welcome, " + parameters.name;
};
// query
Get["/bye"] = parameters =>
{
return "Bye " + Request.Query.name;
};
// post form
Get["/hello"] = parameters =>
{
return View["hello"];
};
Post["/hello"] = parameters =>
{
return "Hello, " + Request.Form.name;
};
// return json
Get["/hey"] = parameters =>
{
var dict = new Dictionary<string, string>();
dict.Add("name", "John");
var jss = new JavaScriptSerializer();
var jsonStr = jss.Serialize(dict);
var response = (Response)jsonStr;
response.ContentType = "application/json";
return response;
};
// return png image
Get["/image"] = parameters =>
{
byte[] data = File.ReadAllBytes("Content/nancy-logo.png");
var response = new Response();
response.ContentType = "image/png";
response.Contents = s => s.Write(data, 0, data.Length);
return response;
};
// error
Get["/error404"] = parameters =>
{
var response = (Response)"404ERROR";
response.WithStatusCode(404);
return response;
};
Get["/"] = parameters =>
{
return View["index"];
};
}
}
}
スポンサーサイト