如何在单个Web应用程序中最好地结合Web Api和MVC

时间:2013-04-14 11:04:57

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

我即将创建一个简单的Web应用程序,我想知道是否应该使用ASP.NET MVC 4新功能Web API

最好的方法是什么?

我做了一些研究,发现有两种选择:

Option 1

使Web Api成为我的服务层,并从控制器调用它来读/写数据,并使用视图模型和剃刀渲染视图。

Option 2

使Web Api成为我的服务层,并使用Javascript直接从视图中调用它。

我不是Option 2的忠实粉丝,因为我觉得我忽略了仅用于页面之间重定向的控制器。此外,我更喜欢使用剃须刀而不是Javascript。

如果我选择Option 1,我是否必须在控制器中创建一个Web API的实例?因为这感觉我做错了什么。

什么是最好的选择?还有其他我未考虑过的选择吗?

如果你能提供一些可以帮助我的参考书或书籍,我将不胜感激。

感谢。

2 个答案:

答案 0 :(得分:16)

我的业务规则通常有另一个图层(可能是不同的项目/程序集,具体取决于应用程序的大小和复杂程度)。您可以将此商业服务或其他适合您案例的内容称为

因此 MVC控制器 API控制器都使用此图层;这使得应用程序保持干燥。

我个人更喜欢只在我的业务层中保留复杂的操作,这意味着如果我需要从我的持久层中读取某些内容以在我的视图中显示,我可以直接在MVC控制器上进行操作。这是个人偏好的问题,但我更喜欢采用 CQRS 方式。

因此,MVC控制器将实例化这些业务服务(或者如果您使用IoC,它们将被注入您的控制器)。对于读取操作,您可以选择直接进入持久层或使用其他读取策略。

您的API控制器也会发生同样的情况,他们将使用这种“常见”服务层。

您无需在MVC控制器上实例化API控制器。 如果您正在开发SPA或类似产品,那么通过AJAX使用Web Api控制器是可以的。

没有一种方法来构建您的应用程序,只有不同的方式,每个人都有或多或少的痛苦。

如果您正在考虑在您的应用程序中引入测试(并且您应该:));那么你应该以一种易于测试它的每个部分的方式构造它。

只需2美分。

答案 1 :(得分:4)

Web API的重点是成为无状态RESTful服务。如果你做得对,就永远不会有它的实例。我意识到这个问题已经过去了,你可能已经亲自了解了这个问题,但答案对你来说并不是一个问题,因为它是对常见问题的回答。

请注意,在谈到Web API时,人们常常谈论的是ApiControllers而不是基本的MVC“控制器”,它们将路由转换为视图。

因此,在您的项目中,您可能有一些“控制器”,它们执行一些基本的视图逻辑,但没有业务逻辑。不要将其与您的服务层混淆,后者是您的业务逻辑和持久性访问的包装。

我和很多人认为ApiControllers不应该与你的MVC应用程序混在一起。请记住,MVC与Web API不能很好地融合。正如Filip W所说:

  

Web API和MVC使用的许多概念,尽管类似于   乍一看,实际上是不兼容的。例如,Web API   属性是System.Web.Http.Filters.Filter和MVC属性   System.Web.Mvc.Filter - 它们不可互换。

最灵活的回答

所以你要做的是创建一个名为api.YourWebsite.com的子域,并在那里构建一个新的Web API ApiController项目。 Web API项目不应该通过ApiControllers和依赖注入实例化和公开业务逻辑。

备选方案1

面向服务的体系结构就是可重用性。如果你想让你的应用程序保持干净,你肯定应该属于SOA。但是,每种情况都不同。如果你永远不会在任何其他应用程序(桌面,机器人,平板电脑,ewPhones等)中使用相同的业务逻辑,那么你有另一种方法。

将您的业务逻辑层创建为另一个项目,并直接从您的Web应用程序访问它。当您的Javascript(Angular / Razor?)控制器进行调用时,它们可以调用您的ViewModel和/或Codebehind或类似的东西,它们可以实例化Business Logic并直接访问它。如果一切都在那里并且不会被重复使用,则无需服务。

备选方案2

继续将您的Web API ApiControllers放在同一个项目中。但是,请确保将它们分离到MVC“控制器”的不同文件夹中。尽管如此,当您的Javascript控制器拨打电话时,他们将对您的网站进行路由呼叫以获得无状态返回。不要将无状态ApiControllers与ViewModels和其他MVC代码混合。

缺点是缺乏SOC。现在,您将服务层和UI层混合在一起,并且您的UI层被迫访问您的业务逻辑层(DLL)。如果备选方案1做到了,那有什么问题?

嗯,错误的是,替代品1是一个没有增长空间的小型应用程序。其他任何东西(最初的计划,或者替代方案2)都应该有UI,它们不知道商业逻辑(或持久性)是否存在。他们应该在不了解后端世界的情况下进行他们的运动。