ASP.NET Web API控制器最佳实践 - 操作定义

时间:2013-05-30 23:45:09

标签: c# rest asp.net-mvc-4 asp.net-web-api .net-4.5

我遇到的情况是我的Web API控制器中的HttpGet操作有多种方法可以根据查询字符串中指定的参数进行调用。

我需要能够处理以下GET请求:

 ~/businesses/{businessId}
 ~/businesses?hasOwnProperty={propertyName}
 ~/businesses?latitude={lat}&longitude={long}&hasOwnProperty={propertyName}

代码示例1:

[HttpGet]
public HttpResponseMessage Get(string hasOwnProperty, ODataQueryOptions<Core.Models.Entities.Business> query)
{
    var businessesREST = _businessRepo.Gets(hasOwnProperty, query);

    response = Request.CreateResponse(HttpStatusCode.OK, businessesREST);
    response.Headers.Location = new Uri(businessesREST.Href);

    return response;
}

[HttpGet]
public HttpResponseMessage Get(double latitude, double longitude, string hasOwnProperty, ODataQueryOptions<Core.Models.Entities.Business> query)
{
    var businessesREST = _businessRepo.GetsByLatLong(latitude, longitude, hasOwnProperty, query);

    response = Request.CreateResponse(HttpStatusCode.OK, businessesREST);
    response.Headers.Location = new Uri(businessesREST.Href);

    return response;
}

[HttpGet]
public HttpResponseMessage GetBusiness(string businessId, ODataQueryOptions<Core.Models.Entities.Business> query)
{
    var businessREST = _businessRepo.Get(businessId, query);

    response = Request.CreateResponse(HttpStatusCode.OK, businessREST);
    response.Headers.Location = new Uri(businessREST.Href);

    return response;
}

有人建议我将这些方法结合起来如下。

代码示例2:

[HttpGet]
public HttpResponseMessage Get(string businessId, double latitude, double longitude, string hasOwnProperty, ODataQueryOptions<Core.Models.Entities.Business> query)
{

    if (!String.IsNullOrEmpty(businessId))
    {
        //GET ~/businesses/{businessId}
        var businessREST = _businessRepo.Get(businessId, query);

        response = Request.CreateResponse(HttpStatusCode.OK, businessREST);
        response.Headers.Location = new Uri(businessREST.Href);
    }
    else
    {
        //GET ~/businesses?hasOwnProperty={propertyName}
        //GET ~/businesses?latitude={lat}&longitude={long}&hasOwnProperty={propertyName}
        var businessesREST = (latitude == double.MinValue || longitude == double.MinValue)
            ? _businessRepo.Gets(hasOwnProperty, query)
            : _businessRepo.GetsByLatLong(latitude, longitude, hasOwnProperty, query);

        response = Request.CreateResponse(HttpStatusCode.OK, businessesREST);
        response.Headers.Location = new Uri(businessesREST.Href);
    }

    return response;

}

我很好奇目前广泛接受的最佳实践是关于行动定义及其背后的推理。

1 个答案:

答案 0 :(得分:7)

由于以下几个原因,采用单独的方法会更好:

  1. 单独对单个操作进行单元测试要容易得多。
  2. 单独执行操作后,更改一个操作的实施意外地更改其他操作的实现的可能性就大大降低。
  3. 组合这些方法意味着一堆参数将为null,并且您将拥有一个隐式契约,该契约应该将哪些参数设置在一起以及哪些参数在不同情况下应为null。这就是你必须添加评论的原因。单独的操作是自我记录的,因为它们使合同更加清晰,如何调用您的API。