在Web Api中使用ViewModel是否有意义?

时间:2013-05-03 18:55:16

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

我开始学习webapi并发现自己在MVC项目中做了有意义的事情,但可能没有意义。

通常在MVC项目中我创建ViewModels并将其用作参数或将它们与视图一起传回。

由于webapi中没有视图,我认为将ViewModel作为参数没有意义。

我想知道我是否应该将我的EF域(代码优先)作为参数,并将数据注释放在这些之上。我通常会将注释放在视图模型属性上,因为我喜欢这个域。

然而,阻止我这样做的是我不是100%清楚我的MVC网站是如何工作的。

MVC网站是否只是吐出简单视图然后你使用Jquery来调用你的webapi,或者你只是调用MVC动作方法直接调用Webapi会调用的相同方法?

如果是第二种方式,那么我宁愿再次将数据注释放在我的视图模型上,然后我将相同的注释放在EF域和VM上,这似乎是多余的。

5 个答案:

答案 0 :(得分:32)

我在使用'事物'

之后花了很长时间的建议。

用于数据绑定的

BindingModels (mvc或api)

关于mvc的观点的

ViewModels (您的api中可能有一些mvc页面,所以最好有一个 为此,这可以是文档,介绍页面,等等。如果没有视图,则可以没有ViewModels)这样做的一个好处是,您可以在Views / web.config中使用ViewModels命名空间引用,并且不会被api资源污染。

用于web api资源的

ResourceModel 。在webapi中,嵌套资源也是在树中任何位置的资源,这在mvc上并不常见,因此命名它们资源非常有意义。

如果要接收资源,可以使用资源模型。请记住,你收到的是你送回的信息。

如果您想要输入的自定义绑定(这应该是您的默认方案),您就拥有了绑定模型。

如果您有任何mvc视图,出于管理目的,文档等等,请使用您的ViewModel。

如果你在mvc上有一个表单页面,你也可以在POST控制器上使用你的BindingModel。无需为MVC或WEBAPI上的帖子设置不同的模型。特别是当模型绑定器或格式化程序可以使用相同的数据注释理解并映射到同一绑定模型时。

有时,您希望使用资源和一些额外字段创建绑定模型。继承是你的朋友。

有时您想要创建具有多个资源的绑定模型和(可选地,额外字段)作为属性的资源是您的朋友。

在MVC世界中,您也可以使用“资源”的概念,但它不常见。当你在同一个项目中拥有MVC和Web Api时,这会派上用场。

如果您需要对任何项目(如文件夹结构,命名空间等)进一步评论,请告诉我。我非常乐意分享我的专业经验。

哦,我忘了,映射策略值得研究。我个人做我自己的映射,但在一个地方拥有这个逻辑是无价的。

编辑: 非常天真的例子

ContactViewModel{

    string Name {get;}
    string LastName {get;}
    List<Country> AvailableCountries {get;}
    Country Country {get;}
    bool IsAdmin {get;}

}

ContactBindingModel{

    string Name {get;set;}
    string LastName {get;set;}
    int Country {get;set;}

}

ContactResourceModel{

    string Name { get;set;}
    string LastName {get;set;}
    Country Country {get;set;}
    string IsAdmin {get;}

}

答案 1 :(得分:28)

除了术语之外,使用绑定模型仍然有用。它们在技术上不再是ViewModels,因为你没有涉及到任何视图。但他们肯定仍然有用。使用它们可以让您利用Model的属性上的属性,并允许您在需要时在API中重复使用它们。还要记住,如果你直接使用你的实体,WebAPI会建模将所有参数绑定到名称匹配的参数,即使你不是故意的。

此外,实体模型是原始数据的表示,但用于绑定的模型是API请求成功处理请求时需要满足的固定合同。在您的实现完成时,最终可能跨越多个实体模型的值,而不是持久存储到数据存储。

答案 2 :(得分:7)

如果您正在尝试构建基于REST的系统,那么ViewModel和View的概念可能非常有用。您可以非常接近地将Resource的概念映射到ViewModel,将表示映射到View。

如果你停下来想一想MVC网站中的视图是什么样的。这是一个HTML文档。包含一堆语义信息,标题,正文,部分,段落,表格等的文档。它不应包含“样式”信息。这是Web浏览器和CSS的工作。当人们开始将HTML视为UI时,人们会感到困惑。它不应该是UI,它是UI的内容。

视图只是使用可以通过网络传输的某种媒体类型的视图模型内容的具体实现。该媒体类型取决于您尝试满足的客户端。

答案 3 :(得分:3)

我们目前正在开发一个使用ASP.Net MVC和ASP.Net Web Api的类似项目。

我们使用ASP.Net MVC生成页面的全局结构。 然后,我们的MVVM javascript实现调用web api来填充客户端视图模型中的返回数据。为此,我们的api返回与前端正在等待的对应的视图模型。

我认为你的api视图模型与MVC ViewModel不同(从MVVM的角度来看,它们不是ViewModels)。

这取决于你对api的使用。例如,对于内部使用,您并不总是需要避免显示您的域模型。因此,您将避免在ViewModel中映射模型并提高性能。 但是在你需要转换模型中的一些属性的情况下,viewModels将极大地帮助你以松散耦合的方式构建代码。

  

由于webapi中没有视图,我认为将ViewModel作为参数没有意义。

我想说你的api最终被你的观点所消耗,有了ViewModel是有意义的。

  

MVC网站是否只是吐出简单视图然后你使用Jquery来调用你的webapi,或者你只是调用MVC动作方法直接调用Webapi会调用的相同方法?

这只是一个选择问题。您可以调用MVC操作来接收生成的视图(以html格式),也可以调用WebApi来接收JSON / XML响应,然后将其与视图中的javascript代码绑定。

答案 4 :(得分:1)

只是添加其他人所说的内容,使用通常称为ViewModel的内容对于验证也很有用。您可以使用数据注释标记类,包括任何验证要求。在您的控制器操作中,您仍然可以使用ModelState强制进行验证,并通过HttpRequestException或仅通过HttpResponseMessage返回相应的消息。