116 votes

Méthode personnalisée noms ASP.NET Web API

Je suis à la conversion à partir de la WCF API Web pour la nouvelle ASP.NET MVC 4 Web API. J'ai un UsersController, et je veux avoir une méthode nommée Authentifier. - Je voir des exemples de la façon de faire GetAll, GetOne, Post et Delete, cependant, que faire si je veux ajouter des méthodes supplémentaires pour ces services? Par exemple, mon UsersService doit avoir une méthode appelée Authentifier où ils passent dans un nom d'utilisateur et mot de passe mais cela ne fonctionne pas.

public class UsersController : BaseApiController
{
    public string GetAll()
    {
        return "getall!";
    }

    public string Get(int id)
    {
        return "get 1! " + id;
    }

    public User GetAuthenticate(string userName, string password, string applicationName)
    {
        LogWriter.Write(String.Format("Received authenticate request for username {0} and password {1} and application {2}",
            userName, password, applicationName));

        //check if valid leapfrog login.
        var decodedUsername = userName.Replace("%40", "@");
        var encodedPassword = password.Length > 0 ? Utility.HashString(password) : String.Empty;
        var leapFrogUsers = LeapFrogUserData.FindAll(decodedUsername, encodedPassword);

        if (leapFrogUsers.Count > 0)
        {
            return new User
            {
                Id = (uint)leapFrogUsers[0].Id,
                Guid = leapFrogUsers[0].Guid
            };
        }
        else
            throw new HttpResponseException("Invalid login credentials");
    }
}

Je peux parcourir pour myapi/api/utilisateurs/ et il va appeler GetAll et je peux parcourir pour myapi/api/users/1 et appellera à Obtenir, cependant si je l'appelle myapi/api/utilisateurs/authentifier?nom d'utilisateur={0} et mot de passe={1}, puis il va appeler Obtenir (ne PAS s'Authentifier) et de l'erreur:

Le dictionnaire de paramètres contient une valeur null pour le paramètre " id "de la non-type nullable "Système".Int32 "pour la méthode" du Système.String Get(Int32)' dans 'Navtrak.Services.WCF.NavtrakAPI.Les contrôleurs.UsersController'. Un paramètre facultatif doit être un type de référence, un type nullable, ou être déclaré comme un paramètre facultatif.

Comment puis-je appeler méthode personnalisée des noms tels que Authentifier?

140voto

Darin Dimitrov Points 528142

Par défaut, la route de la configuration suivante Reposant conventions en ce sens qu'il n'accepte que les Get, Post, Put et Delete noms d'action (regarder l'itinéraire global.asax => par défaut, il ne vous permet pas de spécifier n'importe quel nom de l'action => il utilise le verbe HTTP d'envoi). Ainsi, lorsque vous envoyez une requête GET à l' /api/users/authenticate vous êtes essentiellement l'appel de la Get(int id) action et en passant id=authenticate qui, évidemment, se bloque parce que votre Obtenez l'action s'attend à un nombre entier.

Si vous voulez avoir différents noms d'action que les standards, vous pourriez modifier votre définition de la route en global.asax:

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

Maintenant, vous pouvez naviguer à l' /api/values/getauthenticate pour authentifier l'utilisateur.

89voto

sky-dev Points 1990

C'est la meilleure méthode que j'ai mis au point jusqu'à présent à intégrer supplémentaire méthodes GET, tout en soutenant le RESTE normal méthodes. Ajouter les lignes suivantes à votre WebApiConfig:

routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id = RouteParameter.Optional }, new { id = @"\d+" });
routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}");
routes.MapHttpRoute("DefaultApiGet", "Api/{controller}", new { action = "Get" }, new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });
routes.MapHttpRoute("DefaultApiPost", "Api/{controller}", new {action = "Post"}, new {httpMethod = new HttpMethodConstraint(HttpMethod.Post)});

J'ai vérifié cette solution avec la classe de test ci-dessous. J'ai pu réussir à frapper chaque méthode dans mon contrôleur ci-dessous:

public class TestController : ApiController
{
    public string Get()
    {
        return string.Empty;
    }

    public string Get(int id)
    {
        return string.Empty;
    }

    public string GetAll()
    {
        return string.Empty;
    }

    public void Post([FromBody]string value)
    {
    }

    public void Put(int id, [FromBody]string value)
    {
    }

    public void Delete(int id)
    {
    }
}

J'ai vérifié qu'il prend en charge les demandes suivantes:

GET /Test
GET /Test/1
GET /Test/GetAll
POST /Test
PUT /Test/1
DELETE /Test/1

Notez Que si votre OBTENIR les actions ne commencent pas par " Get " vous voulez peut-être ajouter un HttpGet attribut de la méthode.

22voto

Kinjal Dixit Points 2996

Je suis jours dans le MVC4 monde.

Pour ce que sa vaut le coup, j'ai un SitesAPIController, et j'avais besoin d'une méthode personnalisée, qui peut être appelée comme:

http://localhost:9000/api/SitesAPI/Disposition/0

Avec des valeurs différentes pour le dernier paramètre pour obtenir de l'enregistrement avec des dispositions différentes.

Ce qui a Finalement fonctionné pour moi a été:

La méthode dans le SitesAPIController:

// GET api/SitesAPI/Disposition/1
[ActionName("Disposition")]
[HttpGet]
public Site Disposition(int disposition)
{
    Site site = db.Sites.Where(s => s.Disposition == disposition).First();
    return site;
}

Et ce dans le WebApiConfig.cs

// this was already there
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

// this i added
config.Routes.MapHttpRoute(
    name: "Action",
    routeTemplate: "api/{controller}/{action}/{disposition}"
 );

Aussi longtemps que j'étais de nommage de l' {disposition} comme {id} je rencontre:

{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:9000/api/SitesAPI/Disposition/0'.",
"MessageDetail": "No action was found on the controller 'SitesAPI' that matches the request."
}

Quand je l'ai renommé pour {disposition} il a commencé à travailler. Donc, apparemment, le nom du paramètre correspond à la valeur dans l'espace réservé.

N'hésitez pas à modifier cette réponse pour le rendre plus précis/explicatif.

9voto

Andrew Points 472

Voir cet article pour une plus longue discussion de nommé actions. Il montre aussi que vous pouvez utiliser [HttpGet] attribut au lieu de faire précéder le nom de l'action avec "get".

http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X