web-dev-qa-db-fra.com

Caractère Dot '.' dans MVC Web API 2 pour une requête telle que api / people / STAFF.45287

L'URL que j'essaie de laisser au travail est du type suivant: http://somedomain.com/api/people/staff.33311 ( tout comme les sites tels que LAST.FM autorisent toutes sortes de signes dans leurs URL RESTFul & WebPage, par exemple " http://www.last.fm/artist/psy'aviah "est une URL valide pour LAST.FM).

Ce qui fonctionne sont les scénarios suivants: - http://somedomain.com/api/people/ - qui renvoie toutes les personnes - http://somedomain.com/api/people/staff33311 - fonctionnerait aussi bien, mais ce n'est pas ce que je recherche après. J'aimerais que l'URL accepte un "point" , comme dans l'exemple ci-dessous - http://somedomain.com/api/people/staff.33311 - mais cela me donne une

HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

J'ai mis en place les choses suivantes:

  1. Le contrôleur "PeopleController"

    public IEnumerable<Person> GetAllPeople()
    {
        return _people;
    }
    
    public IHttpActionResult GetPerson(string id)
    {
        var person = _people.FirstOrDefault(p => p.Id.ToLower().Equals(id.ToLower()));
        if (person == null)
            return NotFound();
    
        return Ok(person);
    }    
    
  2. Le WebApiConfig.cs

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
    
        // Web API routes
        config.MapHttpAttributeRoutes();
    
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
    

J'ai déjà essayé de suivre tous les conseils de cet article de blog http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIRequestURL.aspx , mais cela ne fonctionne toujours pas. .. Je pense aussi que c'est assez fastidieux et je me demande s'il n'y a pas d'autre moyen, meilleur et plus sûr.

Nous avons nos identifiants en interne comme ceux-ci, nous allons donc devoir trouver une solution qui corresponde parfaitement au point, de préférence dans le style "." mais je suis ouvert aux suggestions alternatives d'URL si besoin est ...

97
Yves Schelpe

Réglage suivant dans votre web.config fichier devrait résoudre votre problème:

<configuration>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />
94
Kiran Challa

Suffixez l'URL avec une barre oblique, par exemple. http://somedomain.com/api/people/staff.33311/ au lieu de http://somedomain.com/api/people/staff.33311.

130
Danny Varod

J'ai trouvé que en ajoutant ce qui suit avant le standard ExtensionlessUrlHandler résout le problème pour moi:

<add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
     path="api/*"
     verb="*"
     type="System.Web.Handlers.TransferRequestHandler"
     preCondition="integratedMode,runtimeVersionv4.0" />

Je ne pense pas que le nom compte vraiment beaucoup, sauf que cela aide probablement si votre IDE (Visual Studio dans mon cas)) gère la configuration de votre site.

H/T à https://stackoverflow.com/a/15802305/264628

33
BrianS

Je ne sais pas vraiment ce que je fais, mais après avoir joué un peu avec la réponse précédente, j'ai proposé une autre solution, peut-être plus appropriée:

<system.webServer>
<modules>
    <remove name="UrlRoutingModule-4.0" />
    <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
</system.webServer>
23
Greg Z.

J'ai constaté que je devais faire plus que simplement définir l'attribut runAllManagedModulesForAllRequests sur true. Je devais également m'assurer que le gestionnaire d'URL sans extension était configuré pour examiner tous les chemins. De plus, vous pouvez ajouter un paramètre de configuration supplémentaire, ce qui aidera dans certains cas. Voici mon Web.config de travail:

<system.web>
    <httpRuntime relaxedUrlToFileSystemMapping="true" />
</system.web>
<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <handlers>
        <remove name="WebDAV" />
        <remove name="OPTIONSVerbHandler" />
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0"  path="*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
</system.webServer>

Notez, en particulier, que le ExtensionlessUrlHandler-Integrated-4.0 a son attribut path défini sur * par opposition à *. (par exemple).

8
Josh M.

Je me suis retrouvé coincé dans cette situation mais en ajoutant / à la fin de l'URL n'a pas été propre pour moi.

il suffit donc d’ajouter ci-dessous dans la balise web.confighandlers et vous serez prêt à partir.

<add name="Nancy" path="api" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
2
Khawaja Asim

J'ai trouvé que les deux méthodes fonctionnaient pour moi: soit en définissant runAllManagedModulesForAllRequests sur true, soit en ajoutant ExtentionlessUrlHandler comme suit. Enfin, j’ai choisi d’ajouter extensionUrLHandler car runAllManagedModulesForAllRequests a un impact sur les performances du site.

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <remove name="WebDAV" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*" 
       type="System.Web.Handlers.TransferRequestHandler" 
       preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
1
Xuemei

J'ai été confronté au même problème et aux circonstances dans lesquelles je n'étais pas censé jouer IIS et de configuration de site Web. J'ai donc dû le faire fonctionner en apportant des modifications au niveau du code seulement.

Le point simple à retenir est que le cas le plus courant où vous finissez par avoir un caractère de point dans l'URL est lorsque vous obtenez une entrée de l'utilisateur et que vous le transmettez sous la forme d'une chaîne de requête ou d'un fragment d'URL pour transmettre un argument aux paramètres de la méthode d'action. de votre contrôleur.

public class GetuserdetailsbyuseridController : ApiController
{
     string getuserdetailsbyuserid(string userId)
     {
        //some code to get user details
     }
}

Regardez ci-dessous l'URL où l'utilisateur entre son identifiant pour obtenir ses informations personnelles:

http://mywebsite:8080/getuserdetailsbyuserid/foo.bar

Comme vous devez simplement extraire des données du serveur, nous utilisons http GET verb. Lorsque vous utilisez GET, tous les paramètres d'entrée ne peuvent être transmis que dans les fragments d'URL.

Donc, pour résoudre mon problème, j'ai changé le verbe http de mon action en POST. Http POST verb a la possibilité de transmettre toute entrée utilisateur ou non utilisateur dans le corps également. J'ai donc créé une donnée JSON et l'ai passée dans le corps de la requête http POST:

{
  "userid" : "foo.bar"
}

Changez la définition de votre méthode comme ci-dessous:

public class GetuserdetailsbyuseridController : ApiController
{
     [Post]
     string getuserdetailsbyuserid([FromBody] string userId)
     {
        //some code to get user details
     }
}

Note : Plus d'informations sur le moment d'utiliser GET verbe et le moment d'utilisation de POST verbe ici =.

0
RBT