本实验演示如何创建 DTO,以及如何通过模型绑定将 HTML 表单数据转换为复杂对象。
创建 DTO
在 Models 文件夹内创建 Source.cs:
using System.Collections.Generic;namespace MyWebApp.Models{public class Film{public int ID { get; set; }public string Name { get; set; }public int Year { get; set; }public Genre[] Genres { get; set; }public bool IsInStore { get; set; }}public class CreateOrUpdateDTO{public int ID { get; set; }public string Name { get; set; }public int Year { get; set; }public Genre[] Genres { get; set; }public bool IsInStore { get; set; }public Operation Operation { get; set; }}public enum Genre{Action,Adventure,Comedy,Drama,War}public enum Operation{Create,Update,Delete}}
不难看出 Film 是领域模型,CreateOrUpdateDTO 是数据传输对象(DTO)。留心一点就会发现它俩非常相似,只是 DTO 类多了一点信息(Operation 属性)。
创建控制器
创建包含 CreateOrUpdate action 的 FilmController。
FilmController.cs:
using Microsoft.AspNetCore.Mvc;using MyWebApp.Models;namespace MyWebApp.Controllers{public class FilmController : Controller{[HttpGet]public IActionResult CreateOrUpdate(){return View();}[HttpPost]public IActionResult CreateOrUpdate(CreateOrUpdateDTO dto){var film = new Film(){ID = dto.ID,Name = dto.Name,Year = dto.Year,Genres = dto.Genres,IsInStore = dto.IsInStore};if (dto.Operation == Operation.Create){// create a new film ... Note: the ID from the dto will be ignoredreturn View("Created");}else if (dto.Operation == Operation.Update){// update the existing film by IDreturn View("Updated");}else{return View("Error"); // we don't implement the Error view now}}}}
标注 [HttpGet] 的 action 响应 HTTP GET 请求,主要用于将用户导向填表的网页
标注 [HttpPost] 的 action 响应 HTTP POST 请求,用于处理用户的表单提交请求
换句话说,[HttpPost] 标注的 action 执行实际的创建/更新操作。
创建视图
在创建 Views 文件夹下创建 Film 文件夹,然后依次添加如下视图。
CreateOrUpdate.csthml:
<html><body><h1>Create or Update Film</h1><hr /><form action="createorupdate" method="POST"><span>ID</span><input type="text" name="id" /><br /><span>Name</span><input type="text" name="name" /><br /><span>Year</span><select name="year"><option value="2015">2015</option><option value="2016">2016</option><option value="2017">2017</option><option value="2018">2018</option></select><br /><span>Genre</span><input type="checkbox" name="genres" value="action" /><span>Action</span><input type="checkbox" name="genres" value="comedy" /><span>Comedy</span><input type="checkbox" name="genres" value="war" /><span>War</span><br /><span>In Store</span><input type="radio" name="isinstore" value="true" /><span>Yes</span><input type="radio" name="isinstore" value="false" /><span>No</span><br /><input type="submit" name="operation" value="Create" /><input type="submit" name="operation" value="Update" /></form></body></html>
Created.cshtml:
<html><body><h1>The Film is Created!</h1></body></html>
Updated.cshtml
<html><body><h1>The Film is Updated!</h1></body></html>
Error.cshtml
<html><body><h1>Oops, Something Is Wrong!</h1></body></html>
调试与观察
与其他实验不同,本实验的重点在于断点调试标注了 [HttpPost] 的 CreateOrUpdate,观察模型绑定的工作机理。
操作步骤如下:
在 HttpPost 第一行设置断点
填写信息,提交表单
观察表单数据通过模型绑定后的 dto

