1年以上ぶりにNancyFxネタ。日本語の情報があまりないので、色々書いて行こうと思います。
ユーザが増えてくれれば嬉しいですね。
さてNancyFxでは、デフォルトでJsonレスポンスを返すことが出来ます。
Get["/json"] = _ => { var data = new { Id = 1, Name = "rabitarochan", BlogUrl = "http://rabitarochan.hatenablog.com/" }; return Response.AsJson(data); };
ブラウザからこのURLにアクセスすると、以下のようなJsonが返ります。
{ Id: 1, Name: "rabitarochan", BlogUrl: "http://rabitarochan.hatenablog.com/" }
よくよく見てみると、キーがC#のプロパティ名と同じUpperCamelCase
となっていますね。
そのため、JavaScript側でも同じくUpperCamelCase
で扱う必要があります。
ただし、JavaScriptではほとんどの場合、lowerCamelCase
が使われていると思いますので、JavaScript側がちょっと気持ち悪い感じになってしまいます。
できればNancyFxからJsonを返す際に、キーをlowerCamelCase
に変換してくれればベストです。
NancyFxのソースを読んでみましたが、残念ながらキーとなる文字列を変換するオプション等はありませんでした。
(ちなみに、NancyFxは独自のJsonシリアライザを使っています。)
そこでNancy.Serialization.JsonNetの出番です!
リポジトリはこちら。NuGetからもインストール可能です。
https://github.com/NancyFx/Nancy.Serialization.JsonNet
このライブラリは、Jsonレスポンスを返す際のシリアライザとして、C#からJsonを扱う際に一番使われていると思われるライブラリJson.Net
を使うように変更してくれるだけのものです。
そして、Json.Net
のJsonSerializer
クラスを少し変更するだけで、キーをlowerCamelCase
に変換することが可能です!!
設定方法
設定はとても簡単で、シリアライザを継承したクラスを1つ作成することと、それをDIコンテナに登録することだけです。
シリアライザを継承したクラスを作成する
Json.Net
用のシリアライザを継承したクラスを作成します。今回と同じ目的の場合は、以下のコードをコピペでOKです。
詳細については、Json.Net
のドキュメントを参照してください。
public class CustomJsonSerializer : JsonSerializer { public CustomJsonSerializer() { this.ContractResolver = new CamelCasePropertyNamesContractResolver(); } }
DIコンテナに登録する
Bootstrapperクラスにて、DIコンテナのTinyIoc
に先ほど作成したクラスを登録します。
public class Bootstrapper : DefaultNancyBootstrapper { protected override void ConfigureApplicationContainer(Nancy.TinyIoc.TinyIoCContainer container) { base.ConfigureApplicationContainer(container); container.Register(typeof(JsonSerializer), typeof(CustomJsonSerializer)); } }
仕組み
Nancy.Serialization.JsonNet
は、JsonのシリアライザとしてJson.Net
を利用するように変更してくれるプラグインのようなものです。
NancyFxでは、コンテントタイプ毎に任意のシリアライザが登録できる仕組みになっているようです。
(その仕組みまではまだ見ていません。)
デフォルトではJson.Net
のJsonSerializer
をそのまま使用しますが、BootStrapperクラスにて今回作成したようなクラスを登録してあげることで、そちらのクラスが使用される、ということです。
最初に書いたソースはそのままで同じURLにアクセスすると、ちゃんとlowerCamelCase
に変換されていることが分かります。
{ id: 1, name: "rabitarochan", blogUrl: "http://rabitarochan.hatenablog.com/" }
デシリアライズは??
PostされたJsonをC#のクラスに変換する場合は、UpperCamelCase
、lowerCamelCase
関係なく変換してくれます。
変換には、NancyFxが提供しているModelBinding
という仕組みを利用します。
以下の例では、フォームからPostされたパラメータをクラスに変換し、そのままJsonレスポンスとして返しています。
namespace NancyJsonTest.Modules { using Nancy; using Nancy.ModelBinding; // クラスに変換するための拡張メソッド用。 public class HomeModule : NancyModule { // フォーム値用のクラス class TestForm { // input type=text name=userName public string UserName { get; set; } // input type=password name=password public string Password { get; set; } } public HomeModule() { Get["/json"] = _ => { var data = new { Id = 1, Name = "rabitarochan", BlogUrl = "http://rabitarochan.hatenablog.com/" }; return Response.AsJson(data); }; Post["/json"] = _ => { var form = this.Bind<TestForm>(); return Response.AsJson(form); }; } } }
まとめ
このライブラリを利用することで、C#とJavaScriptのプロパティ名の違いがほぼ吸収できると思います。
NancyFxでWebAPIを作成するときは、ぜひこのライブラリを利用してみてください。