2017年2月12日日曜日

バインディング

ViewのデータをPostする際に、Nameの名前が所定のルールに従っていれば自動的に
バインドしてくれるので、Controllerの引数から受け取ることができます。


基本は、InputタグのNameに クラス名.プロパティとかけばバインドしてくれます。
あとは、プロパティがリストだという場合は、 クラス名.プロパティ[インデックス]
クラス自体がリストで受け取るのであれば クラス名[インデックス].プロパティ
といった感じでかけば受け取ることができます。

わかりやすくするため、ViewでHTMLをハードコードします。

Models/Sample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SampleCode.Models
{
    public class Sample
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}

IDとNameを持つだけのクラスです。

適当にHomeという名前のControllerを作成して以下のように書きました

Controllers/HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace SampleCode.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(Models.Sample sample)
        {
            return View();
        }
    }
}
ブレイクポイントを設定して確認します。

Views/Home/Create.cshtml
@{
    ViewBag.Title = "Create";
}

Create

@using (Html.BeginForm()) { @Html.AntiForgeryToken() }




@modelにクラスが設定されていれば、Nameのところでクラス名を省略できます。
Views/Home/Create.cshtml
@model SampleCode.Models.Sample

@{
    ViewBag.Title = "Create";
}

Create

@using (Html.BeginForm()) { @Html.AntiForgeryToken() }



今度は、クラス内にListがある時

Models/Sample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SampleCode.Models
{
    public class Sample
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public List Memo { get; set; }
    }
}



Views/Home/Create.cshtml
@model SampleCode.Models.Sample

@{
    ViewBag.Title = "Create";
}

Create

@using (Html.BeginForm()) { @Html.AntiForgeryToken() }

リストはプロパティ名に[インデックス]番号つければバインドできます




今度は、Dictionaryをモデルに持っている時です
Models/Sample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SampleCode.Models
{
    public class Sample
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public Dictionary Hash { get; set; }
    }
}


Controllers/HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace SampleCode.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(Models.Sample sample)
        {
            return View();
        }
    }
}

Views/Home/Create.cshtml
@model SampleCode.Models.Sample

@{
    ViewBag.Title = "Create";
}

Create

@using (Html.BeginForm()) { @Html.AntiForgeryToken() }

KeyValueのうち、Keyは inputのhiddenに、Valueは取得したいinput要素のNameに指定します。
KeyとValueをペアリングするために Nameにプロパティ名[文字列] が一致する者同士を KeyValueのペアとみなします。

<input type = "hidden" name="プロパティ名[文字列].key" value="キー名" />
<input type = "text" name="プロパティ名[文字列].value" value="値" />

[文字列]はループ処理とかを考えると数字が来やすいけども
keyとvalueをペアリングするための識別子なので、任意の文字を指定できます



今度は、Controllerで受け取る引数をリスト(List)にしてみます。

Models/Sample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SampleCode.Models
{
    public class Sample
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}

Controllers/HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace SampleCode.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(List list)
        {
            return View();
        }
    }
}

Viewes/Home/Create.cshtml
@model SampleCode.Models.Sample

@{
    ViewBag.Title = "Create";
}

Create

@using (Html.BeginForm()) { @Html.AntiForgeryToken() }
基本は、クラス名[数字].プロパティ ですが、modelで明示してあるので省略してあるだけです。



クラス内でListを使い、そのクラスをリストで受けるとなると、今までの方法を組み合わせるだけです
Models/Sample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SampleCode.Models
{
    public class Sample
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public List Memo { get; set; }
    }
}

Controllers/HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace SampleCode.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(List list)
        {
            return View();
        }
    }
}

Views/Home/Create.cshtml
@model SampleCode.Models.Sample

@{
    ViewBag.Title = "Create";
}

Create

@using (Html.BeginForm()) { @Html.AntiForgeryToken() }

何が複数なのかを考えればクラスに[数字]をつけるかプロパティに[数字]をつけるか明確ですね


ちなみに、クラスのインスタンスに、一加工してから格納したいので
ひとまずリストで受け取りたいなんて場合、いちいちクラスを作らなくてもバインドしてくれます
Models/Sample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SampleCode.Models
{
    public class Sample
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}

Controllers/HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace SampleCode.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(List list, List hoge)
        {
            return View();
        }
    }
}
Modelに定義せずに List を用意。
名前をhogeにしたので、Viewにもhogeの名前でnameにつけます。

Views/Home/Create.cshtml
@model SampleCode.Models.Sample

@{
    ViewBag.Title = "Create";
}

Create

@using (Html.BeginForm()) { @Html.AntiForgeryToken() }

これで、 List list にも List hogeにもバインドされます。

0 件のコメント:

コメントを投稿