J'ai un service REST ASP.NET Web API (version 4) où je dois passer un tableau d'entiers.
Voici ma méthode d'action:
public IEnumerable<Category> GetCategories(int[] categoryIds){
// code to retrieve categories from database
}
Et voici l'URL que j'ai essayé:
/Categories?categoryids=1,2,3,4
c#
arrays
rest
asp.net-web-api
Hemanshu Bhojak
la source
la source
Réponses:
Vous avez juste besoin d'ajouter
[FromUri]
avant le paramètre, ressemble à:Et envoyez la demande:
la source
Comme le souligne Filip W , vous devrez peut-être recourir à un classeur de modèle personnalisé comme celui-ci (modifié pour se lier au type réel de paramètre):
Et puis vous pouvez dire:
/Categories?categoryids=1,2,3,4
et l'API Web ASP.NET lieront correctement votrecategoryIds
baie.la source
ModelBinderAttribute
afin qu'il puisse être utilisé directement au lieu de la syntaxe laborieuse utilisant l'typeof()
argument. Tout ce que vous avez à faire est possèdes comme ceci:CommaDelimitedArrayModelBinder : ModelBinderAttribute, IModelBinder
puis fournir un constructeur par défaut qui pousse la définition de type jusqu'à la classe de base:public CommaDelimitedArrayModelBinder() : base(typeof(CommaDelimitedArrayModelBinder)) { }
.System.Collections.Generic.List<long>
commebindingContext.ModelType.GetElementType()
support uniquement lesSystem.Array
typesJ'ai récemment rencontré cette exigence moi-même et j'ai décidé de mettre en œuvre un
ActionFilter
pour gérer cela.Je l'applique comme ça (notez que j'ai utilisé 'id', pas 'ids', car c'est ainsi qu'il est spécifié dans mon itinéraire):
Et l'URL publique serait:
Vous devrez peut-être refactoriser cela pour répondre à vos besoins spécifiques.
la source
Dans le cas où quelqu'un aurait besoin de réaliser la même chose ou une chose similaire (comme supprimer) via
POST
au lieu deFromUri
, utiliserFromBody
et du côté du client (JS / jQuery) param param comme$.param({ '': categoryids }, true)
c #:
jQuery:
Le problème avec,
$.param({ '': categoryids }, true)
c'est que .net s'attend à ce que le corps du message contienne une valeur encodée comme=1&=2&=3
sans nom de paramètre et sans crochets.la source
code to retrieve categories from database
, donc la méthode devrait être une méthode GET, pas POST.Un moyen simple d'envoyer des paramètres de tableau vers une API Web
API
Jquery: envoyer un objet JSON en tant que paramètres de demande
Il générera votre URL de demande comme
../api/categories/GetCategories?categoryIds=1&categoryIds=2&categoryIds=3&categoryIds=4
la source
Vous pouvez essayer ce code pour prendre des valeurs séparées par des virgules / un tableau de valeurs pour récupérer un JSON à partir de webAPI
Production :
la source
Solution ASP.NET Core 2.0 (Swagger Ready)
Contribution
Code
Écrivez le fournisseur (comment MVC sait quel classeur utiliser)
Écrivez le classeur réel (accédez à toutes sortes d'informations sur la demande, l'action, les modèles, les types, etc.)
Enregistrez-le avec MVC
Exemple d'utilisation avec un contrôleur bien documenté pour Swagger
EDIT: Microsoft recommande d'utiliser un TypeConverter pour ces enfants d'opérations sur cette approche. Suivez donc les conseils d'affiches ci-dessous et documentez votre type personnalisé avec un SchemaFilter.
la source
Au lieu d'utiliser un ModelBinder personnalisé, vous pouvez également utiliser un type personnalisé avec un TypeConverter.
L'avantage est qu'il rend les paramètres de la méthode API Web très simples. Vous n'avez même pas besoin de spécifier [FromUri].
Cet exemple concerne une liste de chaînes, mais vous pouvez faire
categoryIds.Select(int.Parse)
ou simplement écrire une IntList à la place.la source
J'ai utilisé à l'origine la solution qui @Mrchief pendant des années (cela fonctionne très bien). Mais quand j'ai ajouté Swagger à mon projet pour la documentation de l'API, mon point final ne s'est PAS présenté.
Cela m'a pris du temps, mais c'est ce que j'ai trouvé. Cela fonctionne avec Swagger et les signatures de votre méthode API sont plus propres:
En fin de compte, vous pouvez faire:
WebApiConfig.cs
Créez une nouvelle classe: CommaDelimitedArrayParameterBinder.cs
Créez une nouvelle classe: StringToIntArrayConverter.cs
Remarques:
la source
Usage:
Demander uri
la source
/
le séparateur? Ensuite, vous pourriez avoir: dns / root / mystuff / path / to / some / resource mapped topublic string GetMyStuff(params string[] pathBits)
Si vous voulez lister / tableau d'entiers, la façon la plus simple de le faire est d'accepter la liste de chaînes séparée par des virgules (,) et de la convertir en liste d'entiers. N'oubliez pas de mentionner [FromUri] attriubte.votre URL ressemble à:
la source
List<string>
au lieu de justestring
? il n'aura qu'une seule chaîne qui est1,2,3,289,56
dans votre exemple. Je proposerai une modification.List<Guid>
Cependant, j'ai été surpris que mon contrôleur ne se lie pas automatiquement à un . Notez que dans Asp.net Core, l'annotation est[FromQuery]
, et elle n'est pas nécessaire.Faites le type de méthode [HttpPost], créez un modèle qui a un paramètre int [] et postez avec json:
la source
public IEnumerable<Category> GetCategories(int[] categoryIds){
- ouais tu pourrais interpréter de différentes manières je suppose. Mais plusieurs fois, je ne veux pas créer de classes wrapper pour le plaisir de créer des wrappers. Si vous avez des objets complexes, cela fonctionnera. La prise en charge de ces cas plus simples est ce qui ne fonctionne pas dès le départ, d'où l'OP.POST
est en fait contraire au paradigme REST. Une telle API ne serait donc pas une API REST.Ou vous pouvez simplement passer une chaîne d'éléments délimités et la placer dans un tableau ou une liste à l'extrémité de réception.
la source
J'ai abordé cette question de cette façon.
J'ai utilisé un message de poste à l'API pour envoyer la liste des entiers en tant que données.
Ensuite, j'ai renvoyé les données sous forme d'innombrables.
Le code d'envoi est le suivant:
Le code de réception est le suivant:
Cela fonctionne très bien pour un ou plusieurs enregistrements. Le remplissage est une méthode surchargée utilisant DapperExtensions:
Cela vous permet d'extraire des données d'une table composite (la liste des identifiants), puis de renvoyer les enregistrements qui vous intéressent vraiment dans la table cible.
Vous pouvez faire de même avec une vue, mais cela vous donne un peu plus de contrôle et de flexibilité.
De plus, les détails de ce que vous recherchez dans la base de données ne sont pas affichés dans la chaîne de requête. Vous n'avez pas non plus à convertir à partir d'un fichier csv.
Vous devez garder à l'esprit lorsque vous utilisez un outil comme l'interface web api 2.x, les fonctions get, put, post, delete, head, etc. ont une utilisation générale, mais ne sont pas limitées à cette utilisation.
Ainsi, bien que la publication soit généralement utilisée dans un contexte de création dans l'interface Web API, elle n'est pas limitée à cette utilisation. Il s'agit d'un appel html régulier qui peut être utilisé à toutes fins autorisées par la pratique html.
De plus, les détails de ce qui se passe sont cachés à ces "regards indiscrets" dont on entend tant parler ces jours-ci.
La flexibilité des conventions de dénomination dans l'interface Web Api 2.x et l'utilisation d'appels Web réguliers signifie que vous envoyez un appel à l'API Web qui induit les espions en erreur en pensant que vous faites vraiment autre chose. Vous pouvez utiliser "POST" pour récupérer vraiment des données, par exemple.
la source
J'ai créé un classeur de modèle personnalisé qui convertit toutes les valeurs séparées par des virgules (uniquement primitives, décimales, flottantes, chaîne) en leurs tableaux correspondants.
Et comment utiliser dans Controller:
la source
Ma solution était de créer un attribut pour valider les chaînes, il fait un tas de fonctionnalités communes supplémentaires, y compris la validation regex que vous pouvez utiliser pour vérifier les nombres uniquement, puis plus tard, je convertis en entiers au besoin ...
Voici comment vous utilisez:
la source