多くの読書をした後、私がやろうとしていたことを行うことは可能であるように見えますが、そうするためには多くの有用なセキュリティ対策を緩和する必要があります. 簡単な回避策があるため、セキュリティ リスクの増大を考慮してこれらの対策を緩和することは意味がありません。
APIで取得していたエラーは次のとおりです。
A potentially dangerous Request.Path value was detected from the client (:)
明らかに、これは文字列の時間部分の要素を区切るために使用されるコロンDateTime
文字です。そこで、以下の変更を行いました。
私の Api アクション メソッドは次のようになります。
[System.Web.Http.HttpGet]
[GET("range?{startDate:datetime}&{endDate:datetime}")]
public HttpResponseMessage Get(DateTime startDate, DateTime endDate)
日付は、パス自体の一部ではなく、クエリ文字列の一部として定義されるようになりました。
クエリ文字列の作成を処理するために、次の拡張メソッドもあります。
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;
}
これは、次のようにクライアント コードで使用されます。
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;
私のアプリケーションの日付サービスは、デフォルトの日付フォーマット文字列を提供するだけで、次のパターンを使用します。
"yyyy-MM-ddTHH:mm:ss"
これから生成される完全な URI は次のようになります。
http://localhost:51258/plots/range?startDate=2013-07-30T21%3A48%3A26&endDate=2013-08-06T21%3A48%3A26
これが将来誰かに役立つことを願っています。