【问题标题】:WebAPI: How to do attribute routing for Post, Put and Delete verbsWebAPI:如何为 Post、Put 和 Delete 动词进行属性路由
【发布时间】:2016-08-05 09:58:51
【问题描述】:

我是 WebAPI 的新手。不知何故,我设法为获取类型请求进行属性路由,但不知道如何为 PostPutDelete 动词执行此操作

请查看我的示例代码并附带修改后的代码,有人会告诉我如何为PostPutDelete 动词进行属性路由。

[RoutePrefix("api/customer")]
public class CustomerController : ApiController
{
    static readonly ICustomerRepository repository = new CustomerRepository();

    [HttpGet, Route("GetAll")]
    public IEnumerable<Customer> GetAllCustomers()
    {
        return repository.GetAll();
    }

    [HttpGet, Route("GetByID/{customerID}")]
    public Customer GetCustomer(string customerID)
    {
        Customer customer = repository.Get(customerID);
        if (customer == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        return customer;
    }

    [HttpGet, Route("GetByCountryName/{country}")]
    public IEnumerable<Customer> GetCustomersByCountry(string country)
    {
        return repository.GetAll().Where(
            c => string.Equals(c.Country, country, StringComparison.OrdinalIgnoreCase));
    }

    public HttpResponseMessage PostCustomer(Customer customer)
    {
        customer = repository.Add(customer);
        var response = Request.CreateResponse<Customer>(HttpStatusCode.Created, customer);

        string uri = Url.Link("DefaultApi", new { customerID = customer.CustomerID });
        response.Headers.Location = new Uri(uri);
        return response;
    }

    public void PutProduct(string customerID, Customer customer)
    {
        customer.CustomerID = customerID;
        if (!repository.Update(customer))
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
    }

    public void DeleteProduct(string customerID)
    {
        Customer customer = repository.Get(customerID);
        if (customer == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        repository.Remove(customerID);
    }
}

客户类

public class Customer
{
    public string CustomerID { get; set; }
    public string CompanyName { get; set; }
    public string ContactName { get; set; }
    public string ContactTitle { get; set; }

    public string Address { get; set; }

    public string Region { get; set; }

    public string PostalCode { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string Phone { get; set; }
    public string Fax { get; set; }
}

【问题讨论】:

    标签: rest asp.net-web-api attributerouting


    【解决方案1】:

    不是 testet,但我认为它应该是这样的:

    [RoutePrefix("api/customer")]
    public class CustomerController : ApiController
    {
        static readonly ICustomerRepository repository = new CustomerRepository();
    
        [HttpGet]
        [Route("")]
        public IEnumerable<Customer> GetAllCustomers()
        {
            return repository.GetAll();
        }
    
        [HttpGet]
        [Route("{customerID}")]
        public Customer GetCustomer(string customerID)
        {
            Customer customer = repository.Get(customerID);
            if (customer == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return customer;
        }
    
        [HttpGet]
        [Route("/GetByCountryName/{country}")]
        public IEnumerable<Customer> GetCustomersByCountry(string country)
        {
            return repository.GetAll().Where(
                c => string.Equals(c.Country, country, StringComparison.OrdinalIgnoreCase));
        }
    
        [HttpPost]
        [Route("")]
        public HttpResponseMessage PostCustomer([FromBody]Customer customer)
        {
            customer = repository.Add(customer);
            var response = Request.CreateResponse<Customer>(HttpStatusCode.Created, customer);
    
            string uri = Url.Link("DefaultApi", new { customerID = customer.CustomerID });
            response.Headers.Location = new Uri(uri);
            return response;
        }
    
        [HttpPut]
        [Route("{customerID}")]
        public void PutProduct(string customerID, [FromBody]Customer customer)
        {
            customer.CustomerID = customerID;
            if (!repository.Update(customer))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
        }
    
        [HttpDelete]
        [Route("{customerID}")]
        public void DeleteProduct(string customerID)
        {
            Customer customer = repository.Get(customerID);
            if (customer == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            repository.Remove(customerID);
        }
    }
    

    【讨论】:

    • 请包括所有动作名称的所有网址,因为我看到你改变了我的路线。比如说我的路线是[HttpGet, Route("GetAll")] 你把它改成了[Route("")] 你能告诉我你改变路线的原因或者我的路线有什么问题吗?我的路线对 REST 兼容不友好?请回答。
    • 如何从浏览器 url 测试帖子操作?如果不可能,请告诉我应该使用哪个工具,特别是如何测试我需要传递客户或客户 json 列表的发布操作。我的客户类添加了。谢谢
    • 我建议您尝试 swagger(nuget 包 Swashbuckle),它将为您生成一个站点,您可以在其中看到所有端点,您甚至可以从那里调用它们(它会为客户添加模板等。 .)。调用 Web 请求的一个好工具是 Postman。
    • 来自 Swashbuckle 我们可以像人们使用 fiddler 那样通过 url 调用 web api 吗?当我们从 fiddler 测试 post 方法时,我们必须手动生成 json 并粘贴到 fiddler 中进行测试。
    • 不,swashbuckle 会为您生成一个 Web 前端,您只需单击几下即可调用这些方法。试一试。 Fiddler 是一个通用的解决方案 - 更强大和更复杂,而 swagger 只是为您生成一个前端来测试您的后端(并且您可以为最常见的语言生成您的客户端(代理)...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    相关资源
    最近更新 更多