Opérations de service (WCF Data Services)
Services de données WCF vous permet de définir des opérations de service sur un service de données pour exposer des méthodes sur le serveur. Comme d'autres ressources du service des données, les opérations de service sont adressées par les URI. Les opérations de service vous permettent d'exposer la logique métier dans un service de données, comme d'implémenter la logique de validation, pour appliquer la sécurité basée sur les rôles, ou exposer des fonctions d'interrogation spécialisées. Les opérations de service sont des méthodes ajoutées à la classe de service de données dérivée de DataService<T>. Comme avec toutes les autres ressources de service de données, vous pouvez fournir des paramètres à la méthode d'opération de service. Par exemple, l'URI d'opération de service suivant (basé sur le service de données Démarrage rapide) transmet la valeur London au paramètre city :
https://localhost:12345/Northwind.svc/GetOrdersByCity?city='London'
La définition de cette opération de service est la suivante :
<WebGet()> _
Public Function GetOrdersByCity(ByVal city As String) As IQueryable(Of Order)
[WebGet]
public IQueryable<Order> GetOrdersByCity(string city)
Vous pouvez utiliser la CurrentDataSource du DataService<T> pour accéder directement à la source de données que le service de données utilise. Pour plus d'informations, consultez Procédure : définir une opération de service (WCF Data Services).
Pour plus d'informations sur l'appel d'une opération de service d'une application cliente .NET Framework, consultez Appel des actions et opérations de service (WCF Data Services).
Spécifications des opérations de service
Les spécifications suivantes s'appliquent lors de la définition d'opérations de service sur le service de données. Si une méthode ne respecte pas ces spécifications définies, elle ne sera pas exposée en tant qu'opération de service pour le service de données.
L'opération doit être une méthode d'instance publique qui est un membre de la classe du service des données.
La méthode d'opération peut accepter des paramètres d'entrée uniquement. Les données envoyées dans le corps du message ne sont pas accessibles par le service de données.
Si des paramètres sont définis, le type de chaque paramètre doit être un type primitif. Toutes les données d'un type non primitif doivent être sérialisées et passées dans un paramètre de chaîne.
La méthode doit retourner un des éléments suivants :
void (Nothing en Visual Basic)
Un type d'entité dans le modèle de données que le service des données expose. .
Une classe primitive telle qu'un entier ou une chaîne.
Afin de prendre en charge les options de requêtes telles que le tri, la pagination et le filtrage, les méthodes d'opération de service doivent retourner IQueryable<T>. Les demande aux opérations de services qui incluent des options de requête sont rejetées pour les opérations qui retournent uniquement IEnumerable<T>.
Afin de prendre en charge l'accès aux entités connexes à l'aide de propriétés de navigation, l'opération de service doit retourner IQueryable<T>.
La méthode doit être annotée avec l'attribut [WebGet] ou [WebInvoke].
[WebGet] permet d'appeler la méthode à l'aide d'une demande GET.
[WebInvoke(Method = "POST")] permet d'appeler la méthode à l'aide d'une demande POST. Les autres méthodes WebInvokeAttribute ne sont pas prises en charge.
Une opération de service peut être annotée avec le SingleResultAttribute, qui spécifie que la valeur de retour de la méthode est une entité unique plutôt qu'une collection d'entités. Cette distinction détermine la sérialisation résultante de la réponse et le mode de représentation des parcours de propriété de navigation supplémentaires dans l'URI. Par exemple, lors de l'utilisation de la sérialisation AtomPub, une instance de type de ressource unique est représentée en tant qu'élément d'entrée et un jeu d'instances est représenté en tant qu'élément « feed ».
Adressage d'opérations de service
Vous pouvez adresser des opérations de service en plaçant le nom de la méthode dans le premier segment de chemin d'accès d'un URI. Par exemple, l'URI suivant accède à une opération GetOrdersByState qui retourne une collection IQueryable<T> d'objets Orders.
https://localhost:12345/Northwind.svc/GetOrdersByState?state='CA'&includeItems=true
En appelant une opération de service, les paramètres sont fournis comme options de requête. L'opération de service précédente accepte un paramètre de chaîne state et une paramètre booléen includeItems qui indique s'il faut inclure les objets associés Order_Detail dans la réponse.
Voici les types de retour valides pour une opération de service :
Types de retour valides |
Règles d'URI |
---|---|
void (Nothing en Visual Basic) – ou – Types d'entité – ou – Types primitifs |
L'URI doit être un segment de chemin d'accès unique qui est le nom de l'opération de service. Les options de requête ne sont pas autorisées. |
L'URI doit être un segment de chemin d'accès unique qui est le nom de l'opération de service. Comme le type de résultat n'est pas un type IQueryable<T>, les options de requête ne sont pas autorisées. |
|
Les segments de chemin d'accès, en plus du chemin d'accès qui est le nom de l'opération de service, sont autorisés. Les options de requête sont aussi autorisées. |
Des segments de chemin d'accès ou des options de requêtes supplémentaires peuvent être ajoutés à l'URI en fonction du type de retour de l'opération de service. En guise d'exemple, l'URI suivant accède à une opération GetOrdersByCity qui retourne une collection IQueryable<T> d'objets Orders, classée par RequiredDate dans l'ordre décroissant, avec les objets Order_Details connexes :
https://localhost:12345/Northwind.svc/GetOrdersByCity?city='London'&$expand=Order_Details&$orderby=RequiredDate desc
Contrôle d'accès des opérations de service
La visibilité des opérations de service à l'échelle du service est contrôlée par la méthode SetServiceOperationAccessRule sur la classe IDataServiceConfiguration d'une manière qui s'apparente au contrôle de la visibilité du jeu d'entités à l'aide de la méthode SetEntitySetAccessRule. Par exemple, la ligne de code suivante dans la définition du service de données permet l'accès à l'opération de service CustomersByCity.
config.SetServiceOperationAccessRule( _
"GetOrdersByCity", ServiceOperationRights.AllRead)
config.SetServiceOperationAccessRule(
"GetOrdersByCity", ServiceOperationRights.AllRead);
Notes
Si une opération de service possède un type de retour qui est masqué en restreignant l'accès sur les jeux d'entités sous-jacents, l'opération de service ne sera pas disponible pour les applications clientes.
Pour plus d'informations, consultez Procédure : définir une opération de service (WCF Data Services).
Déclenchement des exceptions
Nous vous recommandons d'utiliser la classe DataServiceException chaque fois que vous déclenchez une exception dans l'exécution du service de données. Cela est dû fait que l'exécution du service de données sait mapper des propriétés de cet objet exception correctement au message de réponse HTTP. Lorsque vous déclenchez DataServiceException dans une opération de service, l'exception renvoyée est encapsulée dans TargetInvocationException. Pour retourner la base DataServiceException sans TargetInvocationExceptionenglobant, vous devez substituer la méthode HandleException(HandleExceptionArgs) dans DataService<T>, extraireDataServiceException à partir de TargetInvocationException, et le retourner comme erreur de niveau supérieur, comme dans l'exemple suivant :
' Override to manage returned exceptions.
Protected Overrides Sub HandleException(args As HandleExceptionArgs)
' Handle exceptions raised in service operations.
If args.Exception.GetType() = GetType(TargetInvocationException) _
AndAlso args.Exception.InnerException IsNot Nothing Then
If args.Exception.InnerException.GetType() = GetType(DataServiceException) Then
' Unpack the DataServiceException.
args.Exception = _
TryCast(args.Exception.InnerException, DataServiceException)
Else
' Return a new DataServiceException as "400: bad request."
args.Exception = _
New DataServiceException(400, args.Exception.InnerException.Message)
End If
End If
End Sub
// Override to manage returned exceptions.
protected override void HandleException(HandleExceptionArgs args)
{
// Handle exceptions raised in service operations.
if (args.Exception.GetType() ==
typeof(TargetInvocationException)
&& args.Exception.InnerException != null)
{
if (args.Exception.InnerException.GetType()
== typeof(DataServiceException))
{
// Unpack the DataServiceException.
args.Exception = args.Exception.InnerException as DataServiceException;
}
else
{
// Return a new DataServiceException as "400: bad request."
args.Exception =
new DataServiceException(400,
args.Exception.InnerException.Message);
}
}
}