読者です 読者をやめる 読者になる 読者になる

.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?}");
});