c# - 使用模型类与 DTO 的后期操作

标签 c# asp.net-web-api asp.net-core .net-core dto

此 MSDN link解释了为什么将 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);
}

我想我的问题是:Post/Put 操作应该采用模型还是 DTO 参数?

更新: 从答案来看,即使在 post/put 操作的情况下,看起来也建议使用 dto,但这将导致另一个问题,在 post 操作的情况下如何从 dto 映射到模型类?假设我们使用 AutoMapper,我发现了很多链接,例如 thisthis警告不要在反向映射中使用它(即 dto => 模型类)。

最佳答案

首先,是的,您应该始终使用 DTO。无论您处理的是常规网站还是 API,您都不应该永远直接保存从发布数据实例化的对象。这打开了一个巨大的安全漏洞,人们可以在其中操纵发布数据并进行各种恶作剧。具有讽刺意味的是,你实际上可以绑定(bind)到你的实体类,但如果你这样做,你不应该保存那个实例,而是创建一个新实例,映射来自已发布实例的数据,然后保存你创建的那个实例 - 重要的部分从不保存发布的实例。使用 View 模型/DTO 只会让您更清楚地知道您应该执行等式的映射部分,因此这是推荐的方法。

就 AutoMapper 而言,建议不要用于反向映射,因为在映射到将要保存到数据库的内容时涉及许多细微​​差别。特别是当您涉及 Entity Framework 之类的 ORM 时。您可以使用 AutoMapper,但您只需要了解所有这些细微差别并相应地处理它们。一般来说,在这些情况下手动进行映射可能更容易,无论如何,因为它通常涉及 AutoMapper 之类的大量配置,从长远来看,您不会节省太多精力。手动映射就像听起来一样。如果您要创建一个新的 Book,那么您只需新建一个 Book 的实例。如果您要修改现有的 Book,您会从数据库中提取它的一个实例。无论哪种方式,您现在都有一个 Book 实例和一个类似 BookDTO 的实例,它们是根据发布数据创建的。然后你只需:

book.Title = bookDto.Tile;
// etc.

对于作者关系之类的东西,您可能需要进行额外的查询。例如:

var author = _context.Authors.SingleOrDefault(x => x.Name == bookDto.AuthorName);
book.Author = author;

关于c# - 使用模型类与 DTO 的后期操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52031936/

相关文章:

c# - ASP.NET Core WebApp 不是基于 Travis CI 构建的

c# - Sharepoint Web 服务 GetListItems View 名称

c# - 如何将 List<T> 转换为 List<dynamic> WPF

c# - "Selecting"或 "Wrapping"一个 IQueryable 以便它仍然可查询

azure - 通过 Web api 将文件上传到 Azure blob

asp.net-web-api - 是否有可能单独使用 allow anonymous 属性并删除 swagger 授权?

c# - iTextSharp 国际文本

c# - 创建 Controller 失败,表明 Controller 需要无参数公共(public)构造函数

c# - .Net Core 2.0 授权总是返回 401

c# - 如何使用 ASP.NET Core 仅在一种方法中获得所需的依赖项