2013-08-05 20 views
5

Tôi gặp một số vấn đề khi nhận được truy vấn phạm vi ngày được chấp nhận bởi WebAPI của tôi. Theo như tôi có thể nói từ tất cả mọi thứ tôi đã đọc này nên được làm việc nhưng tôi vẫn nhận được 400 Bad Request phản ứng.Sử dụng HttpClient để gửi ngày trong URL bằng cách sử dụng AttributeRouting

đường API của tôi trông như thế này:

[System.Web.Http.HttpGet] 
    [GET("range/{start:datetime}/{end:datetime}")] 
    public HttpResponseMessage Get(DateTime start, DateTime end) 

Tôi đang sử dụng thư viện AttributeRouting và theo this page URL Tôi đang yêu cầu nên được tốt.

URL yêu cầu của tôi trông như thế này:

http://localhost:51258/plots/range/2013-07-29T21:58:39/2013-08-05T21:58:39 

Tôi có bộ này trên bộ điều khiển RoutePrefix("plots") đó là nơi các bit plots của tuyến đường URL đến từ đâu.

Nếu tôi bỏ thời gian ra khỏi các đối tượng DateTime mọi thứ hoạt động tốt nhưng tôi cần thời gian trôi qua.

+0

Nó có thể là bởi vì đó không phải là một định dạng DateTime tiêu chuẩn trong C#. Phần ngày là tốt, và do đó là thời gian, tuy nhiên T ở giữa chúng làm cho nó không chuẩn. Tôi sẽ thử thay thế nó bằng một không gian. Nếu điều đó làm việc thì bạn sẽ biết cần phải làm gì. – evanmcdonnal

+0

Tôi đã thêm T vì nó không hoạt động với khoảng trắng hoặc không gian được mã hóa. Theo Mike Wasson (trong liên kết trang), việc bổ sung T là hợp pháp và nên làm việc. – Jammer

+0

Bạn đã thêm regex anh ta đã đề cập (trong liên kết) vào DateTime của bạn chưa? Sau đó, chỉ những ngày có dạng "yyyy-mm-dd" mới khớp. – Gloria

Trả lời

7

Sau khi thực hiện rất nhiều lần đọc, có vẻ như tôi có thể làm những gì tôi đã cố gắng nhưng nó đòi hỏi phải thư giãn nhiều biện pháp bảo mật hữu ích để làm như vậy. Vì có cách giải quyết đơn giản nên việc thư giãn các biện pháp này trong điều kiện rủi ro bảo mật tăng lên không có ý nghĩa.

Các lỗi tôi đã nhận được ở các API là:

A potentially dangerous Request.Path value was detected from the client (:) 

Rõ ràng đây là những nhân vật ruột sử dụng để tách các yếu tố của phần thời gian của DateTime chuỗi. Vì vậy, tôi đã thực hiện các thay đổi sau.

phương pháp hành động Api của tôi bây giờ trông như thế này:

[System.Web.Http.HttpGet] 
[GET("range?{startDate:datetime}&{endDate:datetime}")] 
public HttpResponseMessage Get(DateTime startDate, DateTime endDate) 

Ngày hiện được xác định như là một phần của chuỗi truy vấn chứ không phải là các bộ phận của con đường riêng của mình.

Để xử lý việc tạo ra các chuỗi truy vấn tôi cũng có phương pháp mở rộng sau:

public static string ToQueryString(this NameValueCollection source, bool removeEmptyEntries) 
{ 
    return source != null ? "?" + String.Join("&", source.AllKeys 
     .Where(key => !removeEmptyEntries || source.GetValues(key).Any(value => !String.IsNullOrEmpty(value))) 
     .SelectMany(key => source.GetValues(key) 
      .Where(value => !removeEmptyEntries || !String.IsNullOrEmpty(value)) 
      .Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), value != null ? HttpUtility.UrlEncode(value) : string.Empty))) 
     .ToArray()) 
     : string.Empty; 
} 

nào được sử dụng trong mã khách hàng của tôi như thế này:

var queryStringParams = new NameValueCollection 
    { 
     {"startDate", start.ToString(_dateService.DefaultDateFormatStringWithTime)}, 
     {"endDate", end.ToString(_dateService.DefaultDateFormatStringWithTime)} 
    }; 

var response = httpClient.GetAsync(ApiRootUrl + "plots/range" + queryStringParams.ToQueryString(true)).Result; 

Các dịch vụ ngày trong ứng dụng của tôi chỉ cần cung cấp chuỗi định dạng ngày mặc định và sử dụng mẫu này:

"yyyy-MM-ddTHH:mm:ss" 

URI hoàn chỉnh được tạo ra từ hình thức này trông giống như:

http://localhost:51258/plots/range?startDate=2013-07-30T21%3A48%3A26&endDate=2013-08-06T21%3A48%3A26 

Hy vọng điều này sẽ giúp người khác trong tương lai.

1

: là ký tự dành riêng trong URL nhưng có thể chấp nhận được trong chuỗi truy vấn.Vì vậy, nếu nó hoạt động cho việc định tuyến của bạn, bạn chỉ đơn giản là có thể sử dụng:

[System.Web.Http.HttpGet] 
[GET("range")] 
public HttpResponseMessage Get(DateTime start, DateTime end) 

và yêu cầu URL của bạn có thể trông như thế này:

http://localhost:51258/plots/range?start=2013-07-29T21:58:39&end=2013-08-05T21:58:39