【问题标题】:WebApi and MVC 4: GetById and services in separate projectWebApi 和 MVC 4:GetById 和单独项目中的服务
【发布时间】:2013-04-05 19:20:35
【问题描述】:

我正在使用 webapi,MVC 4 项目。 (使用存储库模式和工作单元) 我有两个问题

1) WebApi 的GetById 应该返回实体还是HttpResponseMessage? 如果是HttpResponseMessage,那么应该是……

[System.Web.Http.HttpGet]
public HttpResponseMessage Get(int id)
{
    var car = Uow.Cars.GetById(id);
    return car == null ? Request.CreateResponse(HttpStatusCode.OK, car) : Request.CreateResponse(HttpStatusCode.NotFound,);
}

[System.Web.Http.HttpGet]
public HttpResponseMessage Get(int id)
{
    var car= Uow.Cars.GetById(id);
    if (car!= null) {
        return car;
    }
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}

我想关注 RESTfull 响应。

2) 将 webapi 服务与 UI 分开是否合乎逻辑?我的意思是在一个 webapi 项目中,具有基本 ApiController 和 CRUD http 操作的控制器,因此可以直接从任何地方/任何设备调用它们,然后另一个 webapi/MVC4 项目将调用 webapi 项目的服务?

我之所以这样问,是因为在同一个控制器中,服务和返回 View 的处理听起来像是将服务耦合到将使用它的客户端。

例如: 从此(在同一个 webapi 控制器中):

[System.Web.Http.HttpGet]
public HttpResponseMessage Get(int id)
{
    var car = Uow.Cars.GetById(id);
    return car!= null ? Request.CreateResponse(HttpStatusCode.OK, car) : Request.CreateResponse(HttpStatusCode.NotFound,);
}

public ViewResult Details(long id)
{
    return View(Get(id));
}

去这个:

public ViewResult Details(long id)
{
    return View(webapiService.Cars.Get(id));
}

在服务中实现 Get。

【问题讨论】:

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


    【解决方案1】:

    您可以使用HttpResponseMessage 或实体Car 作为返回类型。如果您使用HttpResponseMessage,您将在创建响应时对自定义某些 HTTP 属性进行更多控制。

    当操作创建资源时,使用HttpResponseMessage 作为返回类型为您提供了非常灵活的选项来设置状态代码 (201) 和可以访问创建的资源的位置。请参阅此post 了解更多信息。

    REST 不关心你使用哪种方式,它关心的是当调用者请求资源时,服务器应该以调用者可以接受的格式返回资源,并带有适当的状态代码(如果存在则为 200,否则为 404)。

    如果确实可以选择服务可以从不同的客户端使用,您可以将 WebAPI 控制器移动到单独的项目中,否则请避免这样做。一旦您将 WebAPI 控制器移动到一个单独的项目中,那么当您尝试从 MVC 项目中的 javascript 使用它时,您将面临跨域问题。

    【讨论】:

      【解决方案2】:

      第 1 点: 在 Web API 的情况下从操作返回实体是合乎逻辑的,但是我们无法控制 HttpResponseMessage 属性(如 HttpStatusCode)。除了返回实体始终是一种更清洁的方法。我们可以在各自的过滤器中控制序列化、格式化等来完成我们的工作。但是您永远不能选择返回 car/HttpResponseMessage,因为编译器不会让您编译返回类型为 HttpResponseMessage 且返回类型为 Car 的方法。

      第 2 点: 为视图和休息调用使用单独的控制器是个好主意。我建议让控制器具有相同的名称但在不同的命名空间中,然后分别路由处理 http 调用(但在其余调用之前添加“/api/”。在同一控制器中为 ViewResult 和 HttpResponseMessage/Car 提供不同的操作是一种选择也一样,但没有那么干净和独立。

      【讨论】:

      • 关于 Point1 的答案。我知道如果返回类型是 HttpResponseMessage,我无法返回 Car。我的问题是 RESTfull 对此有何看法。调用方是否期望实体?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-05
      • 2019-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多