WebMatrix 2:RESTful?な Web アプリケーション (2)

執筆日時:

WebMatrix 2:RESTful?な Web アプリケーション - だるろぐ の続き。とりあえず、

って感じにマッピングされるように頑張ってみた。

# ~/Posts.cshtml

@{ Layout = "_SiteLayout.cshtml"; }

@try{ switch (UrlData[0].ToUpper()) { case "": // <- / へアクセスするととりあえず UrlData[0] には string.empty が入るっぽい case "LIST": if (!IsPost) // GET { @List() } else // POST { throw new ApplicationException(); } break;

case "NEW": case "CREATE": // <- ビューを書き換えるのがめんどいので if (!IsPost) // GET { @New(UrlData[1]) } else // POST { Create(); } break;

case "EDIT": case "UPDATE": if (!IsPost) // GET { @Edit(UrlData[1]) } else // POST { Update(UrlData[1].AsInt()); } break;

case "REMOVE": case "DELETE": if (!IsPost) // GET { @Remove(UrlData[1]) } else // POST { Delete(UrlData[1].AsInt()); } break;

default: if (!IsPost) // GET { @Show(UrlData[0]) } else // POST { throw new ApplicationException(); } break; } } catch (Exception e) { <p><span class="badge error">Error</span> @e.Message</p> }

@functions { dynamic FindPostByIdOrTitle(string param) { int id = 0; dynamic post;

using (var db = Database.Open("db")) { if (int.TryParse(param, out id)) { var query = "SELECT * FROM Post WHERE Id=@0"; post = db.QuerySingle(query, id); } else { var query = "SELECT * FROM Post WHERE Title=@0"; post = db.QuerySingle(query, param); } }

if (post == null) throw new HttpException(404, string.Format( @"Post ""{0}"" is not found.", param) );

return post; }

HelperResult List() { var query = "SELECT * FROM Post ORDER BY CreatedAt DESC";

using (var db = Database.Open("db")) { var posts = db.Query(query); Page.Title = "Archives"; return RenderPage("~/Views/Posts/_ListPosts.cshtml", posts); } }

HelperResult Show(string param) { var post = FindPostByIdOrTitle(param); Page.Title = post.Title; return RenderPage("~/Views/Posts/_ShowPost.cshtml", post); }

HelperResult New(string param) { Page.Title = "New Post:" + param != string.Empty ? param : "Untitled"; return RenderPage("~/Views/Posts/_NewPost.cshtml"); }

HelperResult Edit(string param) { var post = FindPostByIdOrTitle(param); Page.Title = "Edit: " + post.Title; return RenderPage("~/Views/Posts/_EditPost.cshtml", post); }

HelperResult Remove(string param) { var post = FindPostByIdOrTitle(param); Page.Title = "Remove: " + post.Title; return RenderPage("~/Views/Posts/_RemovePost.cshtml", post); }

void Create() { var query = "INSERT INTO Post (Title, Body, CreatedAt, UpdatedAt)"

  • "VALUES(@0, @1, @2, @3)"; var title = Request["Title"]; var body = Request["body"]; var now = DateTime.Now;

using (var db = Database.Open("db")) { db.Query(query, title, body, now, now); var key = db.QueryValue("SELECT @@IDENTITY"); Response.Redirect("~/Posts/" + key.ToString()); } }

void Update(int id) { var query = "UPDATE Post SET Title=@0, Body=@1, UpdatedAt=@2 WHERE Id=@3"; var title = Request["Title"]; var body = Request["body"]; var now = DateTime.Now;

using (var db = Database.Open("db")) { db.Query(query, title, body, now, id); Response.Redirect("~/Posts/" + id.ToString()); } }

void Delete(int id) { var query = "DELETE FROM Post WHERE Id=@0";

using (var db = Database.Open("db")) { db.Query(query, id); Response.Redirect("~/Posts/"); } } }

あんまり気に入らない。なんか当初の目標とズレてきたし。

でも、よく考えたら、Web Form で GET/POST しかリクエストできないとしても、JavaScript だったらできるわけだよね。そんな Web Form の仕様に合わせなくてもいいんじゃね?

そんなことを考えていたら、こんなナイスなページを見つけた。

HTML5より前のHTMLでは、フォームで利用できるHTTPメソッドはGETとPOSTだけである。そのため、PUTやDELETEを使う場合には、JavaScriptが必要になる(JavaScriptでのHTTPリクエストを参照)。一部のケータイのブラウザのように、JavaScriptをサポートしていないブラウザでは、PUTやDELETEはPOSTで代用しなければならない。PUTやDELETEをPOSTで代用する方法には、以下の2つがあるが、フォームで利用できるのは、パラメータ_methodを利用する方法だけである。

http://wiki.unfindable.net/webbook2/index.php/Web%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%8b%e3%82%89%e3%81%aePUT%e3%81%a8DELETE

あーこれだ! Rails でもやっていたやつだよね?

というわけで、これベースでまた書き直しする。そのあとは、Twitter/Facebook 認証を追加することにしたいと思ってる。