Je dois implémenter la méthode WebAPI suivante:
/api/books?author=XXX&title=XXX&isbn=XXX&somethingelse=XXX&date=XXX
Tous les paramètres de chaîne de requête peuvent être null. C'est-à-dire que l'appelant peut spécifier de 0 à tous les 5 paramètres.
Dans MVC4 beta je faisais ce qui suit:
public class BooksController : ApiController
{
// GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01
public string GetFindBooks(string author, string title, string isbn, string somethingelse, DateTime? date)
{
// ...
}
}
MVC4 RC ne se comporte plus comme ça. Si je spécifie moins de 5 paramètres, il répond par un 404
en disant:
Aucune action n'a été trouvée sur le contrôleur "Livres" correspondant à la demande.
Quelle est la signature de méthode correcte pour le faire se comporter comme avant, sans avoir à spécifier le paramètre facultatif dans le routage d'URL?
Ce problème a été résolu dans la version régulière de MVC4. Maintenant vous pouvez faire:
public string GetFindBooks(string author="", string title="", string isbn="", string somethingelse="", DateTime? date= null)
{
// ...
}
et tout fonctionnera hors de la boîte.
Il est possible de transmettre plusieurs paramètres en tant que modèle unique, comme suggéré par vijay. Cela fonctionne pour GET lorsque vous utilisez l'attribut de paramètre FromUri. Cela indique à WebAPI de remplir le modèle à partir des paramètres de requête.
Le résultat est une action de contrôleur plus propre avec un seul paramètre. Pour plus d'informations, voir: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
public class BooksController : ApiController
{
// GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01
public string GetFindBooks([FromUri]BookQuery query)
{
// ...
}
}
public class BookQuery
{
public string Author { get; set; }
public string Title { get; set; }
public string ISBN { get; set; }
public string SomethingElse { get; set; }
public DateTime? Date { get; set; }
}
Il prend même en charge plusieurs paramètres, tant que les propriétés ne sont pas en conflit.
// GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01
public string GetFindBooks([FromUri]BookQuery query, [FromUri]Paging paging)
{
// ...
}
public class Paging
{
public string Sort { get; set; }
public int Skip { get; set; }
public int Take { get; set; }
}
Mise à jour :
Afin de vous assurer que les valeurs sont facultatives, veillez à utiliser des types de référence ou des nullables (ex. Int?) Pour les propriétés des modèles.
Utilisez les valeurs par défaut initiales pour tous les paramètres comme ci-dessous
public string GetFindBooks(string author="", string title="", string isbn="", string somethingelse="", DateTime? date= null)
{
// ...
}
si vous souhaitez transmettre plusieurs paramètres, vous pouvez créer un modèle au lieu de transmettre plusieurs paramètres.
au cas où vous ne voudriez pas passer un paramètre, vous pouvez aussi y sauter, et votre code sera propre et net.
Les valeurs par défaut ne peuvent pas être fournies pour les paramètres non déclarés 'optional
'
Function GetFindBooks(id As Integer, ByVal pid As Integer, Optional sort As String = "DESC", Optional limit As Integer = 99)
Dans votre WebApiConfig
config.Routes.MapHttpRoute( _
name:="books", _
routeTemplate:="api/{controller}/{action}/{id}/{pid}/{sort}/{limit}", _
defaults:=New With {.id = RouteParameter.Optional, .pid = RouteParameter.Optional, .sort = UrlParameter.Optional, .limit = UrlParameter.Optional} _
)