ASP.NET WebApi操作返回类型

时间:2014-04-27 21:28:58

标签: asp.net-web-api

我的行为应该回归什么?

  1. 键入的对象/集合:CustomerIEnumerable<Order>
  2. HttpResponseMessage
  3. IHttpActionResult
  4. 返回后两者之一的最佳方式是什么?我应该使用Ok还是Content辅助方法?

1 个答案:

答案 0 :(得分:2)

框架将所有操作结果转换为HttpResponseMessage,因此列出的三个操作的结果将是相同的。但是,最后一个是将结果返回给客户端的首选方法,因为它更简洁。让我们来看看三个选项。

假设有一个像这样的产品库:

public interface IProductRepository
    {
        Product FindProductById(int productId);
    }

    public class ProductRepository : IProductRepository
    {
        private List<Product> products = new List<Product>();
        private int _nextId = 1;

        public ProductRepository()
        {
            Add(new Product { Name = "Tomato soup", Category = "Groceries", Price = 1.39M });
            Add(new Product { Name = "Yo-yo", Category = "Toys", Price = 3.75M });
            Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M });
        }

        public IEnumerable<Product> GetAll()
        {
            return products;
        }

        public Product FindProductById(int id)
        {
            return products.Find(p => p.Id == id);
        }

        public Product Add(Product item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            item.Id = _nextId++;
            products.Add(item);
            return item;
        }

    }

产品控制器:

public class ProductsController : ApiController
    {
        private IProductRepository _repository;

        public ProductsController()
        {
            _repository = new ProductRepository();
        }

  }

现在,添加一个get对象,将对象作为结果返回。

        [Route("products/{productId}")]
        public Product GetReturnsObjects(int productId)
        {
            Product product = _repository.FindProductById(productId);

            if(product ==null)   //Throwing the exception skips the entire Http Response pipeline
                throw new HttpResponseException(HttpStatusCode.NotFound);

            return product;
        }

如您所见,为了返回除Product之外的任何内容,我们必须使用适当的HttpStatusCode抛出异常。这样做会跳过响应管道,除非HttpConfiguration中有异常过滤器。

接下来,让我们创建返回HttpResponseMessage或IHttpActionResult的GET方法

        [Route("messageproducts/{productId}")]
        public HttpResponseMessage GetReturnResponseMessage(int productId)
        {
             Product product = _repository.FindProductById(productId);

            if(product ==null)
                return new HttpResponseMessage(HttpStatusCode.NotFound);

            return Request.CreateResponse(HttpStatusCode.OK, product);
        }

         [Route("actionresultproducts/{productId}")]
        public IHttpActionResult GetReturnsActionResult(int productId)
        {
              Product product = _repository.FindProductById(productId);

            if (product == null)
                return NotFound();


            return Ok(product);   //Same as Content(HttpStatusCode.OK, product);
        }

显然,后者更短,更简洁。

关于Ok()或Content(),出于同样的原因,你应该使用Ok()。

希望这有帮助。