本实验演示如何创建 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 ignored
return View("Created");
}
else if (dto.Operation == Operation.Update)
{
// update the existing film by ID
return 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