Tại sao FromBody
và FromUri
các thuộc tính cần thiết trong ASP.NET Web API`?
Sự khác biệt giữa việc sử dụng các thuộc tính và không sử dụng chúng là gì?
Tại sao FromBody
và FromUri
các thuộc tính cần thiết trong ASP.NET Web API`?
Sự khác biệt giữa việc sử dụng các thuộc tính và không sử dụng chúng là gì?
Câu trả lời:
Khi API Web ASP.NET gọi một phương thức trên bộ điều khiển, nó phải đặt các giá trị cho các tham số, một quá trình gọi là ràng buộc tham số .
Theo mặc định, API Web sử dụng các quy tắc sau để liên kết các tham số:
Nếu tham số là loại "đơn giản" , API Web sẽ cố gắng lấy giá trị từ URI . Các kiểu đơn giản bao gồm các kiểu nguyên thủy .NET (int, bool, double, v.v.), cộng với TimeSpan, DateTime, Guid, thập phân và chuỗi, cộng với bất kỳ loại nào có trình chuyển đổi loại có thể chuyển đổi từ chuỗi.
Đối với các loại phức tạp , API Web cố gắng đọc giá trị từ nội dung thư , sử dụng trình định dạng loại phương tiện.
Vì vậy, nếu bạn muốn ghi đè hành vi mặc định ở trên và buộc API Web đọc một loại phức tạp từ URI, hãy thêm [FromUri]
thuộc tính vào tham số. Để buộc API Web đọc một loại đơn giản từ thân yêu cầu, hãy thêm [FromBody]
thuộc tính vào tham số.
Vì vậy, để trả lời câu hỏi của bạn, nhu cầu của các thuộc tính [FromBody]
và [FromUri]
API trong Web chỉ đơn giản là ghi đè, nếu cần, hành vi mặc định như được mô tả ở trên. Lưu ý rằng bạn có thể sử dụng cả hai thuộc tính cho một phương thức điều khiển, nhưng chỉ cho các tham số khác nhau, như được trình bày ở đây .
Có rất nhiều thông tin trên web nếu bạn google "ràng buộc tham số web api".
JustGetIt
phục vụ cho cùng một mục đích là thêm nhiều thuộc tính như [FromBody, FromQuery]
vv
Hành vi mặc định là:
Nếu tham số là một nguyên thủy loại (int
,bool
,double
, ...), cố gắng Web API để có được giá trị từ URI của yêu cầu HTTP.
Đối với các loại phức tạp (ví dụ: đối tượng của riêng bạn Person
:), API Web cố gắng đọc giá trị từ phần thân của yêu cầu HTTP.
Vì vậy, nếu bạn có:
... sau đó bạn không phải thêm bất kỳ thuộc tính nào ( [FromBody]
cũng không phải[FromUri]
).
Nhưng, nếu bạn có một kiểu nguyên thủy trong cơ thể , thì bạn phải thêm [FromBody]
vào trước tham số loại nguyên thủy trong phương thức điều khiển WebAPI của bạn. (Bởi vì, theo mặc định, WebAPI đang tìm kiếm các kiểu nguyên thủy trong URI của yêu cầu HTTP.)
Hoặc, nếu bạn có một loại phức tạp trong URI của mình , thì bạn phải thêm [FromUri]
. (Bởi vì, theo mặc định, WebAPI đang tìm kiếm các loại phức tạp trong phần thân của yêu cầu HTTP theo mặc định.)
Các loại nguyên thủy:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post([FromBody]int id)
{
}
// api/users/id
public HttpResponseMessage Post(int id)
{
}
}
Các loại phức tạp:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post(User user)
{
}
// api/users/user
public HttpResponseMessage Post([FromUri]User user)
{
}
}
Điều này hoạt động miễn là bạn chỉ gửi một tham số trong yêu cầu HTTP của mình. Khi gửi nhiều , bạn cần tạo một mô hình tùy chỉnh có tất cả các tham số của bạn như thế này:
public class MyModel
{
public string MyProperty { get; set; }
public string MyProperty2 { get; set; }
}
[Route("search")]
[HttpPost]
public async Task<dynamic> Search([FromBody] MyModel model)
{
// model.MyProperty;
// model.MyProperty2;
}
Từ tài liệu của Microsoft về ràng buộc tham số trong API Web ASP.NET :
Khi một tham số có [FromBody], API Web sử dụng tiêu đề Kiểu nội dung để chọn một trình định dạng. Trong ví dụ này, loại nội dung là "application / json" và thân yêu cầu là một chuỗi JSON thô (không phải là một đối tượng JSON).Nhiều nhất một tham số được phép đọc từ nội dung thư.
Điều này sẽ làm việc:
public HttpResponseMessage Post([FromBody] string name) { ... }
Điều này sẽ không hoạt động:
// Caution: This won't work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Lý do cho quy tắc này là phần thân yêu cầu có thể được lưu trữ trong luồng không được đệm mà chỉ có thể được đọc một lần.
Chỉ cần thêm vào câu trả lời ở trên ..
[FromUri] cũng có thể được sử dụng để liên kết các loại phức tạp từ các tham số uri thay vì truyền tham số từ chuỗi truy vấn
Ví dụ:
public class GeoPoint
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
[RoutePrefix("api/Values")]
public ValuesController : ApiController
{
[Route("{Latitude}/{Longitude}")]
public HttpResponseMessage Get([FromUri] GeoPoint location) { ... }
}
Có thể được gọi như:
http://localhost/api/values/47.678558/-122.130989
Khi một tham số có [FromBody], API Web sử dụng tiêu đề Kiểu nội dung để chọn một trình định dạng. Trong ví dụ này, loại nội dung là "application / json" và thân yêu cầu là một chuỗi JSON thô (không phải là một đối tượng JSON).
Nhiều nhất một tham số được phép đọc từ nội dung thư. Vì vậy, điều này sẽ không hoạt động:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Lý do cho quy tắc này là phần thân yêu cầu có thể được lưu trữ trong luồng không được đệm mà chỉ có thể được đọc một lần
Vui lòng truy cập trang web để biết thêm chi tiết: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api