Using HttpClient to Send Dates in URL Using AttributeRouting

北慕城南 提交于 2019-12-19 19:43:33

问题


I'm having some problems getting a date range query accepted by my WebAPI. As as far as I can tell from everything I've read this should be working but I still get 400 Bad Request responses.

My API route looks like this:

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

I'm using the AttributeRouting library and according to this page the URL I'm requesting should be fine.

My request URL looks like this:

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

I have this set on the controller RoutePrefix("plots") which is where the plots bit of the URL route comes from.

If I strip the times off the DateTime objects everything works fine but I need the times passed.


回答1:


After doing a lot of reading it appears that it is possible to do what I was attempting to do but it requires relaxing a lot of useful security measures in order to do so. Since there is a simple workaround it just doesn't make sense to relax these measures in light of increased security risks.

The error I was getting at the API was:

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

Obviously this is the colon characters used to separate the elements of the time portion of the DateTime string. So I have made the following changes.

My Api action method now looks like this:

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

The dates are now defined as part of the query string rather than parts of the path itself.

To handle the creation of the query string I also have the following extension method:

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;
}

Which is used in my client code like this:

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;

The date service in my application simply provides the default date formatting string and uses this pattern:

"yyyy-MM-ddTHH:mm:ss"

The complete URI that is produced from this looks like:

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

Hope this helps someone else in the future.




回答2:


: is a reserved character in the URL but it's acceptable in a query string. So if it works for your routing you could simply use:

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

and your URL request can look like this:

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


来源:https://stackoverflow.com/questions/18067712/using-httpclient-to-send-dates-in-url-using-attributerouting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!