如何将一个ViewModel用于WebApi中的所有CRUD操作

时间:2017-02-12 14:51:42

标签: c# asp.net-mvc asp.net-web-api

我正在asp.net中创建一个小API。它与MVC webapp结合在一起。我打算让webapp使用它自己的API,而不是创建两个做同样事情的后端。

我正在努力尝试将重复的代码保持在最低限度,以便在API中创建一个模型以用于"传入" (Post,Put)和"传出" (获得)行动。

我有一个名为Event的类,它包含易于序列化为JSON的属性以及一些复杂类型。我创建了一个名为EventViewModel的模型(是否适合在API中将其称为 view 模型?),并使用一些额外的属性从复杂类型中获取Name

理想情况下,我想重新使用此模型,但在定义[Required]标签时,我的逻辑会崩溃......

我首先考虑在每个API操作上使用[Bind(Include() Exclude()]。这听起来像是一个可行的解决方案吗?

人们使用了哪些其他解决方案?

谢谢!

1 个答案:

答案 0 :(得分:1)

以下是一些想法。

我会为视图(Controller)和api(ApiController)使用单独的控制器,因为我们讨论的是两种不同的数据表示。我不会将控制器用作api,因为它们都返回不同的类型。 api控制器以不同的方式使用状态代码。例如。 ApiController.Delete返回状态代码204 No Content,而Controller返回状态代码200 Ok以及视图。

您可以调用Controller ViewModels和ApiController DTO的模型。无论哪种情况,它们都只是简单的对象。除了验证(您可以使用ModelState测试)并且不使用实体对象之外,不要在这些对象中放置任何逻辑。

出于您已经遇到的原因,请勿将models / dto用于多种用途。只需使用简单的对象,只使用一次,保持简单。在这种情况下,如果你想改变一些你知道它不会破坏你的应用程序的东西。

您可以使用可以继承的基类来保存代码。这也为您提供了为不同对象编写扩展一次的优势。

但是如果你坚持重用对象,你可以决定不在Api中使用ModelState.Validate。我想在那种情况下会忽略[required]标签,但我不确定。至于对象,我不会使用JsonIgnore / Xmlignore,而是设置默认值。在这种情况下,序列化时将省略这些属性。使用POST和GET的对象变得容易。

    [DefaultValue(0)]
    public int Id { get; set; } = 0;

使用存储库。您可以像在api控制器中一样在控制器中调用存储库。这是您可以真正保存代码的地方。

对于Api(不是CRUD),我更喜欢编写返回匿名对象的专用linq查询,并将其选择到dto中。这提供了多个优点。有时我使用扩展(在IQueryable上)来保存代码。

你可能想考虑使用像automapper这样的东西来保存代码,但我不推荐这样做。