Mos*_*bdo 5 c# dto asp.net-web-api .net-core asp.net-core
这个 MSDN链接解释了为什么将 DTO 类用于 Web API 是一种很好的做法。这是可以理解的,让我困惑的是在同一页面中,post 方法使用模型类而不是简单的 DTO 类,如下所示:
[ResponseType(typeof(BookDTO))]
public async Task<IHttpActionResult> PostBook(Book book)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Books.Add(book);
await db.SaveChangesAsync();
// New code:
// Load author name
db.Entry(book).Reference(x => x.Author).Load();
var dto = new BookDTO()
{
Id = book.Id,
Title = book.Title,
AuthorName = book.Author.Name
};
return CreatedAtRoute("DefaultApi", new { id = book.Id }, dto);
}
Run Code Online (Sandbox Code Playgroud)
我想我的问题是:Post/Put 操作应该采用模型还是 DTO 参数?
更新:从答案来看,即使在 post/put action 的情况下,似乎也建议使用 dto,但这会导致另一个问题,如何在 post action 的情况下从 dto 映射到 Model 类?假设我们使用 AutoMapper,我发现了很多链接,例如this和this警告不要在反向映射中使用它(即 dto => Model 类)。
首先,是的,您应该始终使用 DTO。无论你正在处理一个正规的网站或API,你应该永远不会直接保存对象从POST数据实例化。这打开了一个巨大的安全漏洞,人们可以在其中操纵帖子数据并进行各种恶作剧。具有讽刺意味的是,您实际上可以绑定到您的实体类,但如果您这样做了,您不应该保存该实例,而是创建一个新实例,映射来自已发布实例的数据,然后保存您创建的实例 - 重要的是部分从不保存发布的实例。使用视图模型/DTO 只会使您更明显地应该执行等式的映射部分,因此是推荐的方法。
就 AutoMapper 而言,建议不要用于反向映射,因为映射到将要保存到数据库的内容涉及许多细微差别。特别是当您涉及实体框架等 ORM 时。您可以使用 AutoMapper,但您只需要了解所有这些细微差别并相应地处理它们。一般来说,无论如何,在这些情况下手动进行映射可能更容易,因为它通常涉及 AutoMapper 之类的配置,从长远来看,您不会为自己节省太多精力。手动映射就像听起来一样。如果您正在创建一个 new Book,那么您只需新建一个Book. 如果您正在修改现有的Book的,则从数据库中提取该实例的实例。无论哪种方式,Book以及一个类似 的实例BookDTO,它是从发布数据创建的。那么你只需:
book.Title = bookDto.Tile;
// etc.
Run Code Online (Sandbox Code Playgroud)
对于诸如作者关系之类的事情,您可能需要进行额外的查询。例如:
var author = _context.Authors.SingleOrDefault(x => x.Name == bookDto.AuthorName);
book.Author = author;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4222 次 |
| 最近记录: |