2013-08-05 6 views
5

Ho riscontrato alcuni problemi nel ricevere una query dell'intervallo di date accettata da WebAPI. Per quanto posso dire da tutto ciò che ho letto, dovrebbe funzionare, ma ho ancora risposte 400 Bad Request.Utilizzo di HttpClient per l'invio di date nell'URL mediante AttributeRouting

mio percorso API simile a questa:

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

Sto utilizzando la libreria AttributeRouting e secondo this page l'URL che sto richiedente dovrebbero andare bene.

mio URL richiesta assomiglia a questo:

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

ho questo set sul controller RoutePrefix("plots") che è dove l'plots po 'del percorso URL proviene.

Se togli i tempi dagli oggetti DateTime, tutto funziona correttamente ma ho bisogno dei tempi passati.

+0

Potrebbe essere perché non è un formato standard DateTime in C#. La parte di data va bene, e così è il tempo, tuttavia la T tra di loro lo rende non standard. Proverei a sostituirlo con uno spazio. Se funziona, saprai cosa deve essere fatto. – evanmcdonnal

+0

Ho aggiunto il T dal momento che non ha funzionato con uno spazio o uno spazio codificato. Secondo Mike Wasson (nel link alla pagina) l'aggiunta della T è legale e dovrebbe funzionare. – Jammer

+0

Hai aggiunto la regex che ha menzionato (nel link) al tuo DateTime? Quindi solo le date nella forma "aaaa-mm-gg" corrisponderanno. – Gloria

risposta

7

Dopo aver letto molte letture, è possibile eseguire ciò che stavo tentando di fare, ma è necessario attenuare molte misure di sicurezza utili per farlo. Poiché esiste una soluzione semplice, non ha senso rilassare queste misure alla luce dei maggiori rischi per la sicurezza.

L'errore che è stato sempre al API era:

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

Ovviamente questo è il colon caratteri utilizzati per separare gli elementi della parte di tempo della stringa DateTime. Quindi ho apportato le seguenti modifiche.

Il mio metodo di azione Api ora assomiglia a questo:

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

Le date sono ora definiti come parte della stringa di query piuttosto che parti del percorso stesso.

Per gestire la creazione della stringa di query Ho anche il seguente metodo di estensione:

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

che viene utilizzato nel mio codice cliente come questo:

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; 

Il servizio di data nella mia applicazione fornisce semplicemente la stringa di formattazione della data predefinita e utilizza questo modello:

"yyyy-MM-ddTHH:mm:ss" 

L'URI completo prodotto da questo è simile a:

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

Spero che questo aiuti qualcun altro in futuro.

1

: è un carattere riservato nell'URL ma è accettabile in una stringa di query.Quindi, se funziona per il vostro percorso si può semplicemente utilizzare:

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

e la vostra richiesta URL può apparire come segue:

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