web-dev-qa-db-fra.com

Comment gérer les itinéraires hiérarchiques dans l'API Web ASP.NET?

Actuellement, j'ai deux contrôleurs

1 - Contrôleur parent

2 - Contrôleur enfant

J'accède à mon contrôleur parent comme ceci

someurl\parentcontroller

Maintenant, je veux accéder à mon contrôleur pour enfants comme celui-ci

someurl\parentcontroller\1\childcontroller

Cette dernière URL doit renvoyer tous les enfants d'un parent particulier.

J'ai cet itinéraire actuellement dans mon fichier global.asax

routes.MapHttpRoute ("Route1", "{controller}/{id}", new { id = RouteParameter.Optional });

Je ne sais pas comment puis-je atteindre ma hiérarchie parent\id\child. Comment dois-je configurer mes itinéraires pour y parvenir? Des idées?

36
Haris Hasan

Configurez les itinéraires comme ci-dessous. Le {param} est facultatif (utilisez si vous en avez besoin):

routes.MapHttpRoute(
           name: "childapi",
           routeTemplate: "api/Parent/{id}/Child/{param}",
           defaults: new { controller = "Child", param = RouteParameter.Optional }
  );

routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{id}",
         defaults: new { id = RouteParameter.Optional }
  );

Appelez ensuite l'enfant APi comme/api/Parent/1/enfant Le parent peut être appelé simple comme/api/Parent /

Le contrôleur enfant:

    public class ChildController : ApiController
    {     
        public string Get(int id)
        {
          //the id is id between parent/{id}/child  
          return "value";
        }
        .......
    }
31
Abhijit_K

Depuis l'API Web 2, vous pouvez désormais utiliser les attributs de route pour définir un routage personnalisé par méthode,

[Route("api/customers/{id:guid}/orders")]
public IEnumerable<Order> GetCustomerOrders(Guid id) {
   return new Order[0];
}

Vous devez également ajouter la ligne suivante à la méthode d'initialisation WebApiConfig.Register (),

  config.MapHttpAttributeRoutes();

Article complet, http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

18
Daniel Halan

Je voulais gérer cela d'une manière plus générale, au lieu de câbler un ChildController directement avec controller = "Child", comme l'a fait Abhijit Kadam. J'ai plusieurs contrôleurs enfants et je ne voulais pas avoir à mapper un itinéraire spécifique pour chacun, avec controller = "ChildX" et controller = "ChildY" encore et encore.

Mon WebApiConfig ressemble à ceci:

config.Routes.MapHttpRoute(
  name: "DefaultApi",
  routeTemplate: "api/{controller}/{id}",
  defaults: new { id = RouteParameter.Optional }
);
  config.Routes.MapHttpRoute(
  name: "ChildApi",
  routeTemplate: "api/{parentController}/{parentId}/{controller}/{id}",
  defaults: new { id = RouteParameter.Optional }
);

Mes contrôleurs parents sont très standard et correspondent à l'itinéraire par défaut ci-dessus. Un exemple de contrôleur enfant ressemble à ceci:

public class CommentController : ApiController
{
    // GET api/product/5/comment
    public string Get(ParentController parentController, string parentId)
    {
        return "This is the comment controller with parent of "
        + parentId + ", which is a " + parentController.ToString();
    }
    // GET api/product/5/comment/122
    public string Get(ParentController parentController, string parentId,
        string id)
    {
        return "You are looking for comment " + id + " under parent "
            + parentId + ", which is a "
            + parentController.ToString();
    }
}
public enum ParentController
{
    Product
}

Quelques inconvénients de ma mise en œuvre

  • Comme vous pouvez le voir, j'ai utilisé un enum, donc je dois encore gérer les contrôleurs parents à deux endroits distincts. Cela aurait pu tout aussi facilement être un paramètre de chaîne, mais je voulais empêcher api/crazy-non-existent-parent/5/comment/122 de travailler.
  • Il y a probablement un moyen d'utiliser la réflexion ou quelque chose pour le faire à la volée sans le gérer séparément, mais cela fonctionne pour moi pour l'instant.
  • Il ne prend pas en charge les enfants d'enfants.

Il y a probablement une meilleure solution qui est encore plus générale, mais comme je l'ai dit, cela fonctionne pour moi.

10
mo.

Une option au-delà de l'utilisation du routage mvc par défaut est de regarder le routage des attributs - https://github.com/mccalltd/AttributeRouting . Bien que cela demande plus de travail, la décoration de méthodes d'action individuelles offre une tonne de flexibilité lorsque vous devez concevoir des itinéraires complexes. Vous pouvez également l'utiliser en conjonction avec le routage MVC standard.

5
AlexGad