web-dev-qa-db-fra.com

Plusieurs paramètres dans une API Web 2 get

Je veux faire une api Web qui est passé 4 paramètres.

Voici mon itinéraire:

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{email}/{firstname}/{lastname}/{source}"
        );

Voici la signature de la méthode

public string GetId(string email, string firstname, string lastname, string source)

Voici l'URL d'appel

http://fakedomain.com/api/Contacts/[email protected]&firstname=joe&lastname=shmoe&source=123

Je reçois une erreur 404.

Si je règle chaque paramètre sur facultatif dans la configuration de la route et que je configure chaque argument avec une valeur par défaut, il est appelé. Cependant, chaque argument obtient la valeur par défaut et non la valeur transmise.

J'ai l'impression d'être proche, qu'est-ce qui me manque?

19
Nick

Assurez-vous que le paramètre de route api par défaut est défini dans le fichier WebApiConfig.cs.

public static class WebApiConfig
{
    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 }
        );

        config.Routes.MapHttpRoute(
        name: "ContactApi",
        routeTemplate: "api/{controller}/{email}/{firstname}/{lastname}/{source}"
        );
    }
}

http://fakedomain.com/api/Contacts/[email protected]&firstname=joe&lastname=shmoe&source=123

Remarque: j'ai remplacé fakedomain par localhost et cela fonctionne ...

7

Vous n'avez pas besoin d'un enregistrement de routage spécial pour gérer plusieurs paramètres. L'enregistrement de routage que vous avez créé rechercherait l'itinéraire suivant

/api/controller/[email protected]/Dan/FunnyLastName/TheCoffeeShop 

mais vous essayez de passer des paramètres, pas de spécifier un itinéraire.

avec cet enregistrement de routage:

config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional, action = "DefaultAction" });

le point final GET suivant:

public HttpResponseMessage Get(int requestId = 0, string userName = null, string departmentName = null, bool includeCompleted = false)
    {
      //code
    }

pourrait être frappé comme:

 /api/controllername/?requestId=15&username=Dan

ou

/api/controllername/?departmentName=SoftwareEngineering

ou toute autre combinaison de paramètres (ou pas de paramètres car ils ont des valeurs par défaut)

Etant donné que vous avez une action "Nommée" (GetId) au lieu des actions par défaut (GET, POST, PUT ..), cela complique un peu les choses et vous devrez élaborer une route personnalisée pour gérer le nom de l'action. Voici ce que j'utilise pour les noms d'actions personnalisées (un identifiant est requis dans cet exemple)

config.Routes.MapHttpRoute("ActionRoute", "api/{controller}/{action}/{id}");

Votre point de terminaison doit accepter explicitement un paramètre portant le nom "id".

  public HttpResponseMessage LockRequest(int id, bool markCompleted)
    {
        //code
    }

Ce point de terminaison serait atteint sur la route suivante:

/api/controllerName/LockRequest/id?markCompleted=true

Conformément à la spécification RESTful, il est préférable d'éviter les noms d'actions personnalisées lorsque cela est possible. La plupart du temps, vous pouvez vous en tirer avec les verbes HTTP normaux et simplement utiliser des actions nommées pour manipuler des éléments existants (d'où la raison pour laquelle l'ID est requis dans mon exemple). Pour votre code, vous pouvez simplement avoir deux points d'extrémité GET, un qui prend un ID spécifique pour obtenir l'élément, un qui renvoie tous les éléments (y compris les ID) en fonction de "paramètres de recherche".

public HttpResponseMessage Get(int id)
public HttpResponseMessage Get(int requestId = 0, string userName = null, string departmentName = null, bool includeCompleted = false)

Ceux-ci seraient tous deux gérés par l'enregistrement de routage par défaut.

32
vesuvious
public class Parameters
    {
        public int Param1 { get; set; }
        public string Param2 { get; set; }
    }

puis dans votre méthode de contrôleur:

    [ActionName("DoSomething")]
    [HttpPost]
    public IHttpActionResult DoSomething(Parameters myParameters)
    {
        var x = myParameters.Param1;
        var y = myParameters.Param1;
       //do something else..

    }

Et construisez un appel ajax comme ceci:

var request = {
                    Param1 : "1",
                    Param2 : "Mystring"
                };

    function callToMethodController(request) {
        var deferred = $q.defer();
        $http.post('api/object/DoSomething', request)
            .success(function (data) {
                deferred.resolve(data);
            }).error(function (error) {
                deferred.reject('There was an error.');
            });
        return deferred.promise;
    }
0
David Castro