.NET Core 2.0 Previewが出たのでインストールしてみた

Build2017にて、.NET Core 2.0 Preview1の発表があったので、さっそくインストールしてみました。

blogs.msdn.microsoft.com

github.com

なお、Visual Studioで扱うにはVS2017 Preview 15.3が必要とのことなので、これもインストール。

www.visualstudio.com

ASP.NET Core 2.0のRazor Pagesを使ってみる

ASP.NET Core MVCの新機能である、Razor Pagesを試してみることにします。
ASP.NET Core Webアプリケーション(.NET Core)」を選択し、

左上の"ASP.NET Core 1.1"を"2.0"に変更します。

f:id:mrgchr:20170511212417p:plain

すると、"Web Application(Razor Pages)"という項目が表示されるのでこちらを選択します。

f:id:mrgchr:20170511212522p:plain

Razor pages

初期状態のRazor Pagesソリューションは下記のような状態です。

f:id:mrgchr:20170511212713p:plain

「cshtmlの下にcshtml.csがぶら下がっとる。WebFormsみたいやな」と思いましたが、とりあえず覗いてみます。

//About.cshtml.cs
namespace WebApplication4.Pages
{
    public class AboutModel : PageModel
    {
        public string Message { get; set; }

        public void OnGet()
        {
            Message = "Your application description page.";
        }
    }
}

対応するAbout.cshtmlは下記の通りです。

@page
@model AboutModel
@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@Model.Message</h3>

<p>Use this area to provide additional information.</p>

cshtmlの先頭の"@page"ディレクティブが、RazorPagesを示すキーワードになっているようですね。

モデル中のOnGetメソッドがページのGET時に呼ばれることはデバッグ実行すればすぐに確認できました。 PageModelが、従来のControllerとModel(ViewModel)の中間みたいな感じでしょうかね?

POSTにも対応させる

「じゃあPostもOnPost出来るはずだべ?」というわけでやってみます。

//About.cshtml.cs
namespace WebApplication4.Pages
{
    public class AboutModel : PageModel
    {
        public string Message { get; set; }

        public void OnGet()
        {
            Message = "Your application description page.";
        }

        public void OnPost(int id)
        {
            Message = id.ToString();
        }
    }
}
@page
@model AboutModel
@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@Model.Message</h3>

<p>Use this area to provide additional information.</p>

<form method="post">
    <input id="id" name="id" type="number" />
    <input type="submit" value="Submit" />
</form>

おお、ちゃんと動きました。ちょろい。
でも整数一つポストしても楽しくありません。もう少し複雑なオブジェクトをPostしたいです。
例えば、こんな感じはいかがでしょうか?

namespace WebApplication4.Pages
{
    public class AboutModel : PageModel
    {
        public string Message { get; set; }

        public void OnGet()
        {
            Message = "Your application description page.";
        }

        public void OnPost([Bind(Prefix = nameof(Form))]FormModel form)
        {
            Message = form.Value1.ToString() + ", " + form.Value2;
        }

        public class FormModel
        {
            public int Value1 { get; set; }

            public string Value2 { get; set; }
        }

        public FormModel Form { get; set; }
    }
}
@page
@model AboutModel
@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@Model.Message</h3>

<p>Use this area to provide additional information.</p>

<form method="post">
    <input asp-for="Form.Value1" />
    <input asp-for="Form.Value2" />
    <input type="submit" value="Submit" />
</form>

手元では意図通り動作しているようです。
Razor Pagesは、従来のASP.NET MVCと微妙に似ていて微妙に違う、なんとなくWebFormsを思い出させるような感じですね。
これからどうなるかはわかりませんが、これが主流になる日がくるのでしょうか。

おまけ

Startup.csにルーティングが記載されているけど、これはこのサンプルでは正しく機能していないっぽいです。

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});