Các tham số tùy chọn trong định tuyến thuộc tính Api web


90

Tôi muốn xử lý ĐĂNG của lệnh gọi API sau:

/v1/location/deviceid/appid

Tham số bổ sung đến từ Phần thân.

Tất cả điều này làm việc tốt cho tôi. Bây giờ tôi muốn mở rộng mã của mình bằng cách cho phép "deviceid" và / hoặc "appid" và / hoặc BodyData là null:

/v1/location/deviceid
/v1/location/appid
/v1/location/

3 URL này phải trả lời theo cùng một tuyến.

Cách tiếp cận đầu tiên của tôi (yêu cầu BodyData):

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody] location_fromuser BodyData)
{
    return repository.AddNewLocation(deviceid, appid, BodyData);
}

Điều này không hoạt động và trả về lỗi biên dịch:

"Các tham số tùy chọn phải ở cuối"

Hãy thử tiếp theo:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post([FromBody] location_fromuser BodyData, string deviceid = null, string appid = null)

Bây giờ, hàm AddNewLocation () của tôi luôn nhận được BodyData=null- ngay cả khi cuộc gọi gửi Body.

Cuối cùng, tôi đặt tất cả 3 Tham số là tùy chọn:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody location_fromuser BodyData = null)

Đừng làm việc:

Tham số tùy chọn BodyDatakhông được hỗ trợ bởi FormatterParameterBinding.

Tại sao tôi muốn một giải pháp với các Tham số tùy chọn? Bộ điều khiển của tôi chỉ xử lý việc "thêm một Vị trí mới" thông qua một ĐĂNG.

Tôi muốn gửi trên dữ liệu sai các ngoại lệ hoặc thông báo lỗi của riêng tôi. Ngay cả khi cuộc gọi có giá trị bị thiếu. Trong trường hợp này, tôi muốn có thể quyết định đưa ra một ngoại lệ hoặc Cài đặt Mặc định bằng mã của mình.

Câu trả lời:


177

Đối với một yêu cầu đến /v1/location/1234, như bạn có thể tưởng tượng, sẽ rất khó để Web API tự động tìm ra liệu giá trị của phân đoạn tương ứng với '1234' có liên quan đến appidhay không deviceid.

Tôi nghĩ bạn nên thay đổi mẫu tuyến đường của mình để giống [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]và sau đó phân tích cú pháp deiveOrAppidđể tìm ra loại id.

Ngoài ra, bạn cần phải làm cho các phân đoạn trong mẫu tuyến đường là tùy chọn nếu không các phân đoạn được coi là bắt buộc. Lưu ý ?ký tự trong trường hợp này. Ví dụ: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]


56
?bên trong mẫu tuyến đường là những gì tôi đang tìm kiếm. +1
Kal_Torak

4
Tôi sẽ không nói rằng "deviceOrAppId" là lựa chọn thiết kế tốt nhất. Tôi nghĩ rằng API phải luôn biết theo định nghĩa những gì nó sẽ nhận được nếu có thể.
Niels Brinch

14
Chỉ để biết thông tin - Khi chúng ta đánh dấu một tham số là tùy chọn trong hành động sử dụng ?ký tự uri thì chúng ta phải cung cấp giá trị mặc định cho các tham số trong chữ ký phương thức, ví dụ MyMethod (string name = "someDefaultValue", int? Id = null).
RBT

@RBT bạn thật là MVP, tôi đã bối rối ở đó trong một phút. Cảm ơn bạn!
sm

1
Mát mẻ. Rất vui vì nó đã giúp bạn @sm Tôi đã chuyển nhận xét của mình thành câu trả lời để hiển thị tốt hơn vì nó có vẻ hữu ích. Nó sẽ là một phần bổ sung cho bài đăng của Kiran.
RBT

45

Một thông tin khác: Nếu bạn muốn sử dụng Route Constraint , hãy tưởng tượng rằng bạn muốn buộc tham số đó có kiểu dữ liệu int , thì bạn cần sử dụng cú pháp sau:

[Route("v1/location/**{deviceOrAppid:int?}**", Name = "AddNewLocation")]

Cái ? ký tự luôn được đặt trước ký tự } cuối cùng

Để biết thêm thông tin, hãy xem: Tham số URI tùy chọn và Giá trị mặc định


18

Chuyển nhận xét của tôi thành câu trả lời để bổ sung cho câu trả lời của @Kiran Chala vì nó có vẻ hữu ích cho khán giả-

Khi chúng tôi đánh dấu một tham số là tùy chọn trong hành động sử dụng ?ký tự uri thì chúng tôi phải cung cấp các giá trị mặc định cho các tham số trong chữ ký phương thức như được hiển thị bên dưới:

MyMethod(string name = "someDefaultValue", int? Id = null)


Tôi cũng đã nhận xét như vậy.
Jnr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.