2016-06-15 53 views
17

Sự khác nhau cơ bản của các chức năng đó là gì? Tất cả tôi biết là cả ba kết quả trong một 201, đó là thích hợp cho một yêu cầu POST thành công.ASP.net Core RC2 Web API POST - Khi nào sử dụng Create, CreatedAtAction, vs. CreatedAtRoute?

Tôi chỉ làm theo các ví dụ tôi thấy trực tuyến, nhưng họ không thực sự giải thích lý do tại sao họ đang làm những gì họ đang làm.

Chúng ta phải cung cấp tên cho GET của chúng tôi (1 kỷ lục bởi id):

[HttpGet("{id}", Name="MyStuff")] 
public async Task<IActionResult> GetAsync(int id) 
{ 
    return new ObjectResult(new MyStuff(id)); 
} 

mục đích của việc đặt tên này có được chức năng, bên cạnh đó nó "có lẽ" cần thiết cho chức năng POST là gì bên dưới:

[HttpPost] 
public async Task<IActionResult> PostAsync([FromBody]MyStuff myStuff) 
{ 
    // actual insertion code left out 

    return CreatedAtRoute("MyStuff", new { id = myStuff.Id }, myStuff); 
} 

Tôi nhận thấy rằng CreatedAtRoute cũng có tình trạng quá tải không có trong tên tuyến đường.

Ngoài ra còn có CreatedAtAction có thông số tương tự. Tại sao biến thể này tồn tại?

Ngoài ra còn có Created kỳ vọng URL và đối tượng chúng tôi muốn trả lại. Tôi có thể chỉ sử dụng biến thể này và cung cấp một URL không có thật và trả về đối tượng tôi muốn và hoàn thành nó không?

Tôi không chắc chắn tại sao có quá nhiều biến thể chỉ để có thể trả lại 201 cho khách hàng. Trong hầu hết các trường hợp, tất cả những gì tôi muốn làm là trả lại id duy nhất "có khả năng từ một cơ sở dữ liệu" hoặc một phiên bản thực thể của tôi có thông tin tối thiểu. Tôi nghĩ rằng cuối cùng, một phản ứng 201 "nên" tạo ra một tiêu đề vị trí có URL của tài nguyên mới được tạo ra, mà tôi tin rằng tất cả 3 và quá tải của họ kết thúc lên làm. Tại sao tôi luôn nên trả lại tiêu đề vị trí? Ứng dụng JavaScript, ứng dụng gốc dành cho thiết bị di động và máy tính để bàn của tôi không bao giờ sử dụng nó. Ví dụ: nếu tôi phát hành HTTP POST, để tạo báo cáo thanh toán và gửi chúng cho người dùng, URL vị trí như vậy sẽ là gì? (Xin lỗi vì tôi không tìm hiểu sâu hơn về lịch sử Internet để tìm câu trả lời cho điều này.)

Tại sao tạo tên cho hành động và tuyến đường? Sự khác biệt giữa tên hành động và tên tuyến đường là gì?

Tôi đang bối rối về điều này, vì vậy tôi đã sử dụng để trả lại Ok(), trả về 200, không phù hợp cho POST.

Trả lời

22

Có một vài câu hỏi khác nhau ở đây có lẽ nên được tách ra, nhưng tôi nghĩ điều này bao gồm phần lớn các vấn đề của bạn.

Tại sao tạo tên cho hành động và tuyến đường? Sự khác biệt giữa tên hành động và tên tuyến đường là gì?

Trước hết, các hành động và tuyến đường rất khác nhau.

Hành động tồn tại trên bộ điều khiển. Một tuyến đường chỉ định một điểm kết thúc hoàn chỉnh bao gồm một Bộ điều khiển và Hành động và các tham số tuyến đường bổ sung có khả năng khác.

Bạn có thể đặt tên cho tuyến đường, cho phép bạn tham chiếu nó trong ứng dụng của mình.ví dụ

routes.MapRoute(
    name: "MyRouteName", 
    url: "SomePrefix/{action}/{id}", 
    defaults: new { controller = "Section", action = "Index" } 
); 

Lý do cho tên hành động được đề cập trong câu hỏi này: Purpose of ActionName

Nó cho phép bạn để bắt đầu hành động của bạn với một số hoặc bao gồm bất kỳ ký tự mà .net không cho phép trong một số nhận dạng. - Lý do phổ biến nhất là nó cho phép bạn có hai Actions với cùng một chữ ký (xem GET/POST Xóa hành động của bất kỳ điều khiển scaffolded)

sự khác biệt cơ bản của các chức năng là gì?

Tất cả 3 chức năng này thực hiện về cơ bản cùng một chức năng - trả về một đáp ứng 201 Created, với tiêu đề Location trỏ đến url cho phản hồi mới được tạo và chính đối tượng đó trong nội dung. Url phải là url mà tại đó yêu cầu GET sẽ trả về url đối tượng. Điều này sẽ được coi là hành vi 'đúng' trong một hệ thống RESTful.

Đối với ví dụ Mã bưu điện trong câu hỏi của bạn, bạn thực sự muốn sử dụng CreatedAtAction.

[HttpPost] 
public async Task<IActionResult> PostAsync([FromBody]MyStuff myStuff) 
{ 
    // actual insertion code left out 

    return CreatedAtAction("MyStuff", new { id = myStuff.Id }, myStuff); 
} 

Giả sử bạn có định tuyến mặc định được định cấu hình, điều này sẽ thêm tiêu đề Vị trí trỏ đến hành động MyStuff trên cùng một bộ điều khiển.

Nếu bạn muốn url vị trí để trỏ đến một lộ trình cụ thể (như chúng ta định nghĩa trước đó, bạn có thể sử dụng ví dụ

[HttpPost] 
public async Task<IActionResult> PostAsync([FromBody]MyStuff myStuff) 
{ 
    // actual insertion code left out 

    return CreatedAtRoute("MyRouteName", new { id = myStuff.Id }, myStuff); 
} 

Tôi có thể chỉ cần sử dụng biến thể này và cung cấp một URL không có thật và trả lại đối tượng tôi muốn và làm cho nó thực hiện và hơn với?

Nếu bạn thực sự không muốn sử dụng một CreatedResult, bạn có thể sử dụng một đơn giản StatusCodeResult, mà sẽ trả về một 201, mà không có sự Location header hoặc cơ thể.

01.235.
[HttpPost] 
public async Task<IActionResult> PostAsync([FromBody]MyStuff myStuff) 
{ 
    // actual insertion code left out 

    return StatusCode(201); 
} 
+0

Tôi không chắc chắn về .NET Core, nhưng phương thức 'Nội dung (HttpStatusCode, T content)' vẫn tồn tại để trả lại cả mã trạng thái và nội dung? Điều đó sẽ cho phép trả về 201 cùng với đối tượng mới được tạo, mà không bao gồm tiêu đề 'Location'. – afrazier

+1

Quá tải đó dường như không tồn tại nữa, nhưng thực sự có quá tải cho StatusCode mà bạn có thể sử dụng tương tự: 'StatusCode (int httpStatusCode, giá trị đối tượng)' – Sock

+1

Dường như '[HttpGet (" {id} " , Tên = "GetUser", thứ tự = 0)] 'cách tạo một tuyến đường không xuất hiện để làm việc với CreatedAtRoute() – Crob

Các vấn đề liên quan