我正在asp.net中创建一个小API。它与MVC webapp结合在一起。我打算让webapp使用它自己的API,而不是创建两个做同样事情的后端。
我正在努力尝试将重复的代码保持在最低限度,以便在API中创建一个模型以用于"传入" (Post,Put)和"传出" (获得)行动。
我有一个名为Event
的类,它包含易于序列化为JSON的属性以及一些复杂类型。我创建了一个名为EventViewModel
的模型(是否适合在API中将其称为 view 模型?),并使用一些额外的属性从复杂类型中获取Name
理想情况下,我想重新使用此模型,但在定义[Required]
标签时,我的逻辑会崩溃......
我首先考虑在每个API操作上使用[Bind(Include() Exclude()]
。这听起来像是一个可行的解决方案吗?
人们使用了哪些其他解决方案?
谢谢!
答案 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这样的东西来保存代码,但我不推荐这样做。