web-dev-qa-db-fra.com

Paramètres de chaîne de requête facultatifs dans l'API Web ASP.NET

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?

196
frapontillo

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.

288
frapontillo

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.

77
Andrew C

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) 
{
    // ...
}
62
Muhammad Amin

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.

1
vijay

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} _
      )
0
Rizwan Mumtaz