Day05 - 纯 Html - 复杂型别 object + collection

object + collection 指的是 object 里面的某 Property 的资料型态为 collection

今天 ViewModel 都使用相同的结构:

public class ViewModel
{
    public DateTime? OrderDate { get; set; }

    public string[] Items { get; set; }
}

依照 View 的差异,拆成不同 Case 来看 !


Case01 - 不标示 index

  • Controller

    [HttpGet]
    public IActionResult Case01()
    {
        return View();
    }
    
    [HttpPost]
    public IActionResult Case01([FromForm]ViewModel vm)
    {
        return Ok(vm);
    }
    
  • View

    要让 Asp.Net Core MVC Model Binding 至 object 内的 collection

    给定 collection property name 统一的 name 就可以了 !

    <form action="/Day05/Case01" method="post">
      <p>
        <label>订单日期:</label>
        <input type="date" 
               name="OrderDate" />
      </p>
      <div>
        <p>订单项目</p>
        <p>
          <label>项目1:</label>
          <input type="text" 
                 name="Items" />
        </p>
        <p>
          <label>项目2:</label>
          <input type="text" 
                 name="Items" />
        </p>
        <p>
          <label>项目3:</label>
          <input type="text" 
                 name="Items" />
        </p>
      </div>
      <p>
        <button type="submit">送出</button>
      </p>
    </form>
    

网站执行後,在该页面输入资料,并 submit form !

由下图可以看出 request body 的资料,以及後端可以正确回传原本 submit 的资料 !

Image

而 ViewModel 的 collection 资料型态,只要是 ICollection<T> 及衍生的型态 都支援 !


Case02 - 标示 index 范例一

  • Controller

    • Get 语法只有 Action 名称与 Case01 不同,所以就不细看了 !
    • Post 语法都与 Case01 共用,就不写重复的程序码了 !
  • View

    要让 Asp.Net Core MVC Model Binding 至 object 内 collection 的另一个做法

    给定这样的格式 collection property name [index],其中 index 必须是要连续的 !

    <form action="/Day05/Case01" method="post">
      <p>
        <label>订单日期:</label>
        <input type="date" 
               name="OrderDate" />
      </p>
      <div>
        <p>订单项目</p>
        <p>
          <label>项目1:</label>
          <input type="text" 
                 name="Items[0]" />
        </p>
        <p>
          <label>项目2:</label>
          <input type="text" 
                 name="Items[1]" />
        </p>
        <p>
          <label>项目3:</label>
          <input type="text" 
                 name="Items[2]" />
        </p>
      </div>
      <p>
        <button type="submit">送出</button>
      </p>
    </form>
    

网站执行後,在该页面输入资料,并 submit form !

由下图可以看出 request body 的资料,以及後端可以正确回传原本 submit 的资料 !

Image

但这个做法有一个缺点:

只要 index 不连续,就无法 Binding 不连续之後的资料 !

Index 不连续的缺点,可以自行试试 !


Case03 - 标示 index 范例二 - 自行给定 mapping 代号

这个 Case 可以用来解决上一个 Case 不连续的问题 !

先来看执行的结构

  • Controller

    • Get 语法只有 Action 名称与 Case01 不同,所以就不细看了 !
    • Post 语法都与 Case01 共用,就不写重复的程序码了 !
  • View

    <form action="/Day05/Case01"
          method="post">
        <p>
            <label>订单日期:</label>
            <input type="date" 
                   name="OrderDate">
        </p>
        <div>
            <p>订单项目</p>
            <p>
                <input type="hidden"
                       name="Items.index"
                       value="2">
                <label>项目1:</label>
                <input type="text" 
                       name="Items[2]">
            </p>
            <p>
                <input type="hidden"
                       name="Items.index"
                       value="4">
                <label>项目2:</label>
                <input type="text" 
                       name="Items[4]">
            </p>
            <p>
                <input type="hidden"
                       name="Items.index"
                       value="a">
                <label>项目3:</label>
                <input type="text" 
                       name="Items[a]">
            </p>
        </div>
        <p>
            <button type="submit">送出</button>
        </p>
    </form>
    

网站执行後,在该页面输入资料,并 submit form !

由下图可以看出 request body 的资料,以及後端可以正确回传原本 submit 的资料 !

Image

其中以 mapping 的格式来细说,主要是让 FormData 产生以下的格式

PropertyName.index : 特定值
PropertyName[特定值] : PropertyValue
  • PropertyName 为 Binding ViewModel 的 Property Name
  • PropertyValue 为回传的 Property Value
  • 特定值
    • 特定值是我文章内的说明,我目前找不到对应的关键字 !
    • 格式上 - 这个只要是数字或字母,都没有问题。
      • 我试过用 -- 也是可以 !
    • 二行一组,以特定值做为对应 !

针对格式第一行的套用,用 hidden 的 input,可以避免干扰 UI ,又可以放在 Form Tag 内 !

简言之,只要特定值对的上,就可以被 binding 至 collection,所以即使是不连续的 index,仍然可以 binding 完整的资料 !

之後会提到,我如何发现这种结构的 !


这篇先到这里,下一篇来看复杂型别 object + object collection 的 model binding


<<:  从零开始学3D游戏开发:程序基础 Part.2 函式

>>:  从 IT 技术面细说 Search Console 的 27 组数字 KPI (5) 流量:新闻与探索

【Day23】Git 版本控制 - 修改 commit 纪录:reset

上一次有提到说,修改 commit 的方式有以下几种: 把 .git 目录整个删除,暴力破解法,请不...

09 | WordPress 图片区块 Image Block

一般阅读的文章是由标题和段落文字组成,如果是长篇内容,容易让读者感到沉闷。这时候你可以试试适当加入...

TDX api 串接将 ajax 改为 axios,解决 415 错误,解决 headers content-type 无法更新

今天跟着 TDX 的串接说明文(TDX运输资料流通服务API介接范例程序码说明)试图串一串 TDX ...

DAY 14:Simple Factory Pattern,把复杂细节隐藏的小工厂

工厂模式主要有三种不同的实作: Simple Factory Pattern Factory Met...

Day 02-是在 Hello?什麽都要 Hello 一下之 Hello Terraform

软功就是什麽都要 Hello 一下之 Hello terraform 这张就会开始动手做了,还没设定...