Je sais que vous pouvez appliquer un caractère générique dans l'attribut route pour autoriser /
, Comme la date, par exemple:
[Route("orders/{*orderdate}")]
Le problème avec le caractère générique ne s'applique qu'au dernier paramètre de l'URI. Comment résoudre le problème si vous souhaitez avoir l'URI suivant:
[Route("orders/{orderdate}/customers")]
Mise à jour:
Je sais qu'il existe peu d'options pour résoudre le problème en refactorisant le code, veuillez donc ne pas proposer de solution comme:
[Route("orders/customers/{orderdate}")]
"dd-mm-yyyy"
) @ bet .. Je pense que le genericUriParserOptions
n'est plus applicable à .net 4.5 ou version ultérieure ..
Comme suggéré par @ JotaBe , vous devrez peut-être décoder correctement la demande d'URL. Dans la plupart des cas, le %2F
sera automatiquement traduit en barre oblique '/'
. Donc, si vous devez y échapper, vous devrez décoder le '%'
char en premier lieu .. donc votre URL: ressemblera à: www.domain.com/api/orders/23%252F06%252F2015/customers
Remarquez les caractères '%252F'
sera traduit en _ '%2F'
MODIFIER
Ok voici la solution complète (essayé et travaillant pour moi):
En supposant que vous ayez un point de terminaison API comme ceci:
[Route("orders/{date}/customers")]
public HttpResponseMessage Get(string date)
{
}
Dans le web.config vous devrez définir le requestPathInvalidCharacters
à vide ce qui indique à asp.net d'autoriser toutes les requêtes
<system.web>
<httpRuntime targetFramework="4.5" requestPathInvalidCharacters=""/>
</system.web>
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
</system.webServer>
Lorsque le client envoie la demande à l'API, vous devez vous assurer d'échapper au '%'
ainsi:
www.domain.com/api/orders/23%252F06%252F2015/customers
Vous devez ensuite décoder la demande
[Route("orders/{date}/customers")]
public HttpResponseMessage Get(string date)
{
DateTime actualDate = DateTime.Parse(System.Net.WebUtility.UrlDecode(date)); // date is 23/06/2015
}
Comme indiqué dans le commentaire de @AlexeiLevenkov, c'est faux:
Vous ne pouvez pas avoir un paramètre dans l'URL qui accepte les barres obliques, car il s'agit d'un symbole spécial qui sépare chaque fragment d'URL. Ainsi, chaque fois que vous incluez ce symbole dans votre URL, il y aura de nouveaux fragments et un seul paramètre ne peut pas inclure plusieurs fragments.
Si vous voulez plus de détails, lisez ceci , mais ce sont les extraits les plus pertinents:
?
ou #
trouvé dans l'URL. Ainsi, les barres obliques créent uniquement des fragments dans la section du chemin URL avant l'occurrence ou l'un de ces symboles.Ainsi, la chaîne de requête peut inclure des barres obliques, /
, Si vous le souhaitez, et elles ne définiront pas du tout de segments de chemin.
Voici quelques solutions à la question:
[Route("orders/{month}/{day}/{year}/customers")]
puis créer la date côté serveur REMARQUE: votre question d'origine disait "chaîne de requête", et mon commentaire sur le codage faisait référence à la chaîne de requête, qui est le dernier segment d'une URL après le point d'interrogation, si présent, like &id=27
. J'ai corrigé votre question afin qu'elle ne mentionne pas "chaîne de requête", qui n'était pas le bon nom pour ce dont vous avez besoin
Vous pouvez utiliser l'URI [Route("orders/{DD:int}/{MM:int}/{YY:int}}/customers")]
suivante, puis utiliser un classeur de modèle personnalisé pour prendre DD/MM/YY
et les transformer en une date que vous pouvez lier dans votre méthode d'action.
Vous pouvez choisir la façon dont vous voulez gérer les contraintes (aller plus loin avec les regex) ou utiliser la validation et renvoyer 400 si elle ne correspond pas.
L'approche la plus simple consiste à prendre le Day/Month/Year
et le mettre dans le code.
Voici un lien pour traitant de la liaison de modèles .
C # a sa propre méthode qui ignore les règles des séquences d'échappement, le nom de la méthode est ri.UnescapeDataString ( votre paramètre de chaîne de requête ) vous pouvez l'utiliser tout en obtenant la valeur des paramètres