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

问题描述 投票:61回答:5

我开始学习web api并发现自己正在做一些在MVC项目中有意义的东西,但可能没有意义。

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

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

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

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

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

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

asp.net-mvc asp.net-web-api
5个回答
27
投票

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

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


31
投票

在忙于处理这些“事情”之后,我的建议是:

用于数据绑定的BindingModels(mvc或api)

用于mvc上的视图的ViewModel(你的api中可能有一些mvc页面,所以最好有一个这样的地方,这可以是文档,介绍页面,等等。如果没有视图,那么你可以有零视图模型)这样做的好处是,您可以在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;}

}

7
投票

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

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

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


3
投票

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

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

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

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

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

我会说你的api最终会被你的观点所消耗,因此拥有ViewModel是有意义的。

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

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


1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.