Fournisseurs de diffusion en continu (WCF Data Services)
Un service de données peut exposer des données Large Object Binary. Ces données binaires peuvent représenter des flux vidéo et audio, des images, des fichiers de document ou d'autres types de supports binaires. Lorsqu'une entité du modèle de données inclut une ou plusieurs propriétés binaires, le service de données retourne ces données binaires encodées en Base 64 au sein de l'entrée dans le flux de réponse. Étant donné que ce type de chargement et de sérialisation de données binaires volumineuses peut affecter les performances, le protocole Protocole OData (Open Data) définit un mécanisme de récupération des données binaires indépendant de l'entité à laquelle elles appartiennent. Cela s'effectue en séparant l'entité et les données binaires de l'entité dans un ou plusieurs flux de données
Le protocole OData prend en charge les deux mécanismes suivants pour exposer des données binaires sous forme de flux de données liés à une entité :
Ressource multimédia/entrée de lien média
AtomPub (Atom Publishing Protocol) définit un mécanisme pour associer des données binaires en tant que ressource multimédia à une entrée de flux de données, appelée entrée de lien média. Il ne peut exister qu'une ressource multimédia définie pour une entrée donnée de lien média. Une ressource multimédia peut être considérée comme un flux de données par défaut d'une entité. OData hérite de ce comportement de diffusion en continu d'AtomPub.
Flux de ressources nommé
Depuis la version 3 de OData, une entité peut avoir plusieurs flux de ressources associés, qui sont accessibles par nom. Ce mécanisme ne dépend pas d'AtomPub, il est donc possible qu'une entité possède les flux de données nommés de ressource et ne soit pas une entrée de lien multimédia. Il est également possible qu'une entrée de lien média ait les flux nommés. Pour plus d'informations, consultez sur la publication Flux de ressources nommés.
Avec Services de données WCF, vous devez définir des flux de ressources binaires en implémentant des fournisseurs de données en continu. Les implémentations du fournisseur de diffusion en continu fournissent le service de données avec les flux associés à une entité spécifique sous forme d'objets Stream.
La configuration d'un service de données afin de prendre en charge la diffusion en continu de données binaires requiert les étapes suivantes :
Affectez l'entité dans le modèle de données qui a des flux de ressources liés. Chaque fournisseur de données possède ses propres spécifications, et chaque type de flux de ressource binaire est défini dans le modèle de données par un mécanisme différent.
Implémentez les interfaces de fournisseur de flux suivantes :
IDataServiceStreamProvider – requis pour prendre en charge les deux types de flux de ressources binaires.
IDataServiceStreamProvider2 – requis uniquement pour les flux de ressources nommés.
Définir un service de données qui implémente l'interface IServiceProvider. Le service de données utilise l'implémentation GetService pour accéder à l'implémentation du fournisseur de données en continu. Cette méthode retourne l'implémentation de fournisseur de données en continu appropriée.
Autoriser des flux de messages volumineux dans la configuration de l'application Web.
Activer l'accès aux ressources binaires sur le serveur ou dans une source de données.
Les exemples de cette rubrique sont basés sur un exemple de service de diffusion de photos en continu, qui est décrit en détail dans l'article Série Fournisseur de diffusion en continu Data Services : Implémentation d'un fournisseur de diffusion en continu (première partie). Le code source pour ce service exemple est disponible sur la page Exemple de service de diffusion de données en continu de photos dans MSDN Code Gallery.
Définition des flux de ressources dans le modèle de données
La façon dont un flux de ressources binaire est défini dans le modèle de données dépend à la fois du fait que le flux soit une ressource multimédia ou un flux de ressource nommé, et du fournisseur de sources de données qui est utilisé. L'exemple suivant montre la définition d'une ressource multimédia dans les métadonnées retournées par le service de données, où PhotoInfo est une entrée de lien média qui a également un flux de ressources nommé (Thumbnail) défini :
<EntityType Name="PhotoInfo" m:HasStream="true">
<Key>
<PropertyRef Name="PhotoId" />
</Key>
<Property Name="PhotoId" Type="Edm.Int32" Nullable="false"
p9:StoreGeneratedPattern="Identity"
xmlns:p9="https://schemas.microsoft.com/ado/2009/02/edm/annotation" />
<Property Name="FileName" Type="Edm.String" Nullable="false" />
<Property Name="FileSize" Type="Edm.Int32" Nullable="true" />
<Property Name="DateTaken" Type="Edm.DateTime" Nullable="true" />
<Property Name="TakenBy" Type="Edm.String" Nullable="true" />
<Property Name="DateAdded" Type="Edm.DateTime" Nullable="false" />
<Property Name="Exposure" Type="PhotoData.Exposure" Nullable="false" />
<Property Name="Dimensions" Type="PhotoData.Dimensions" Nullable="false" />
<Property Name="DateModified" Type="Edm.DateTime" Nullable="false" />
<Property Name="Comments" Type="Edm.String" Nullable="true" MaxLength="Max"
Unicode="true" FixedLength="false" />
<Property Name="ContentType" Type="Edm.String" Nullable="true" MaxLength="50"
Unicode="true" FixedLength="false" />
<Property Name="Thumbnail" Type="Edm.Stream" Nullable="false" />
</EntityType>
Fournisseur Entity Framework
Lors de l'utilisation du fournisseur Entity Framework, vous devez définir un flux de ressources binaires dans le modèle de données lui-même de l'une des façons suivantes, selon le type de flux :
Flux de ressource multimédia :
Pour indiquer qu'une entité est une entrée de lien média ayant une ressource multimédia associée, ajoutez l'attribut HasStream à la définition du type d'entité dans le modèle conceptuel. Vous devez également ajouter une référence à l'espace de noms xmlns:m=https://schemas.microsoft.com/ado/2007/08/dataservices/metadata soit vers l'entrée de lien média soit vers l'un de ses éléments parents dans le modèle de données.
Flux de ressource nommé :
Un flux de données nommé qui appartient à une entrée de lien multimédia est défini comme une propriété de type Stream dans le modèle conceptuel.
Important
Le type de données Stream est pris en charge par Entity Data Model (EDM) à partir de la version 2.2.Toutefois, dans .NET Framework 4, Entity Framework ne prend pas en charge cette version d'EDM.Pour éviter cela, vous pouvez définir un flux de ressource nommé dans le modèle de données en appliquant NamedStreamAttribute à la classe dans la couche objet de modèle de données qui représente l'entité.Dans cet attribut, le paramètre name est le nom du flux.Nous vous recommandons d'ajouter cet attribut à la classe d'entités en créant une définition de classe partielle gérée dans un fichier de code distinct ; sinon cette personnalisation est écrasée lorsque des classes de données d'entité sont régénérées par Entity Framework.Comme pour le fournisseur de réflexion, le service de données génère une propriété du name fourni de type Stream dans le modèle de données.
Pour obtenir un exemple de d'exposition d'une ressource multimédia à l'aide du fournisseur Entity Framework, consultez l'article Série Fournisseur de diffusion en continu Data Services : Implémentation d'un fournisseur de diffusion en continu (première partie).
Fournisseur de réflexion
Lorsque vous utilisez le fournisseur de réflexion, vous devez identifier un flux de ressources binaires qui appartient à un type d'entité en appliquant des attributs de l'une des façons suivantes à la classe qui est le type d'entité, selon le type de flux :
Flux de ressource multimédia :
Appliquez HasStreamAttribute pour définir un flux (par défaut) de ressource multimédia qui appartient au type, qui est une entrée de lien multimédia.
Flux de ressource nommé :
Appliquez NamedStreamAttribute pour définir un flux de ressource nommé qui appartient au type d'entité, où le paramètre name fourni est le nom du flux.
Fournisseur de services de données personnalisé
Lorsque vous utilisez des fournisseurs de services personnalisés, vous implémentez l'interface IDataServiceMetadataProvider pour définir les métadonnées pour votre service de données. Pour plus d'informations, consultez Fournisseurs de services de données personnalisés (WCF Data Services). Vous devez indiquer qu'un flux de données binaire de ressource appartient à ResourceType de l'une des façons suivantes :
Flux de ressource multimédia :
Définissez la propriété IsMediaLinkEntry sur true sur le ResourceType qui représente le type d'entité, qui est une entrée de lien multimédia.
Flux de ressource nommé :
Ajoutez un ResourceProperty à ResourceType pour chaque flux de données nommé. Un ResourceProperty qui représente un flux de données nommé doit avoir une valeur ResourcePropertyKind de Stream et le ResourceType de la propriété doit être basé sur le type Stream. Utilisez la méthode GetPrimitiveResourceType(Type) sur ResourceType pour créer un ResourceType en fonction du type primitif Stream.
Implémentation des interfaces de fournisseur de flux
Pour créer un service de données qui prend en charge les flux de données binaires, vous devez implémenter au moins l'interface IDataServiceStreamProvider. Cette implémentation permet au service de données de retourner les données binaires comme un flux de données au client et de consommer les données binaires comme un flux de données transmis par le client. Pour prendre en charge les flux nommés, vous devez également implémenter l'interface IDataServiceStreamProvider2. Ce service de données crée une instance de l'interface appropriée chaque fois qu'il doit accéder aux données binaires sous forme de flux.
IDataServiceStreamProvider
L'interface IDataServiceStreamProvider spécifie les membres suivants.
Nom de membre |
Description |
---|---|
Cette méthode est appelée par le service de données pour supprimer à la fois la ressource multimédia correspondante et n'importe quel flux nommé lorsque leur entrée de lien média est supprimée. Lorsque vous implémentez IDataServiceStreamProvider, cette méthode contient le code qui supprime toutes les données binaires diffusées en continu associées à l'entrée de lien média fournie. |
|
Cette méthode est appelée par le service de données pour retourner une ressource multimédia sous forme de flux de données. Lorsque vous implémentez IDataServiceStreamProvider, cette méthode contient le code qui fournit un flux de données utilisé par le service de données pour retourner la ressource multimédia associée à l'entrée de lien média fournie. |
|
Cette méthode est appelée par le service de données pour retourner l'URI utilisé pour demander la ressource multimédia pour l'entrée de lien média. Cette valeur est utilisée pour créer l'attribut src dans l'élément de contenu de l'entrée de lien média et qui est utilisé pour demander le flux de données. Lorsque cette méthode retourne null, le service de données détermine automatiquement l'URI. Utilisez cette méthode lorsque vous devez fournir aux clients un accès direct aux données binaires sans utiliser le fournisseur de flux. |
|
Cette méthode est appelée par le service de données pour retourner la valeur Content-Type de la ressource multimédia associée à l'entrée de lien média spécifiée. |
|
Cette méthode est appelée par le service de données pour retourner l'eTag du flux de données associé à l'entité spécifiée. Cette méthode est utilisée lorsque vous gérez l'accès concurrentiel des données binaires. Lorsque cette méthode retourne la valeur Null , le service de données ne suit pas l'accès concurrentiel. |
|
Cette méthode est appelée par le service de données pour obtenir le flux de données utilisé lors de la réception du flux de données transmis par le client. Lorsque vous implémentez IDataServiceStreamProvider, vous devez retourner un flux de données accessible en écriture sur lequel le service de données écrit le flux de données reçues. |
|
Retourne un nom de type qualifié par un espace de noms qui représente le type que le runtime du service de données doit créer pour l'entrée de lien média associée au flux de données pour la ressource multimédia insérée. |
IDataServiceStreamProvider2
L'interface IDataServiceStreamProvider2 spécifie les membres suivants, qui surchargent les membres de IDataServiceStreamProvider pour prendre un paramètre ResourceProperty qui est un flux de ressource nommé :
Nom de membre |
Description |
---|---|
GetReadStream(Object, ResourceProperty, String, Nullable<Boolean>, DataServiceOperationContext) |
Cette méthode est appelée par le service de données pour retourner un flux nommé. Lorsque vous implémentez IDataServiceStreamProvider2, cette méthode contient le code qui fournit un flux de données utilisé par le service de données pour retourner le flux de données nommé associé à l'entrée de lien média fournie. |
GetReadStreamUri(Object, ResourceProperty, DataServiceOperationContext) |
Cette méthode est appelée par le service de données pour retourner l'URI utilisé pour demander un flux nommé spécifique pour l'entrée de lien média. Cette valeur est utilisée pour créer l'élément atom:link qui est utilisé pour indiquer le flux de données nommé. Lorsque cette méthode retourne null, le service de données détermine automatiquement l'URI. Utilisez cette méthode lorsque vous devez fournir aux clients un accès direct aux données binaires sans utiliser le fournisseur de flux. |
GetStreamContentType(Object, ResourceProperty, DataServiceOperationContext) |
Cette méthode est appelée par le service de données pour retourner la valeur Content-Type d'un flux nommé spécifique associé à l'entrée de lien média spécifiée. |
GetStreamETag(Object, ResourceProperty, DataServiceOperationContext) |
Cette méthode est appelée par le service de données pour retourner l'eTag d'un flux nommé spécifique associé à l'entité spécifiée. Cette méthode est utilisée lorsque vous gérez l'accès concurrentiel des données binaires. Lorsque cette méthode retourne la valeur Null , le service de données ne suit pas l'accès concurrentiel. |
GetWriteStream(Object, ResourceProperty, String, Nullable<Boolean>, DataServiceOperationContext) |
Cette méthode est appelée par le service de données pour obtenir le flux utilisé lors de la réception d'un flux nommé transmis par le client. Lorsque vous implémentez IDataServiceStreamProvider2, vous devez retourner un flux de données accessible en écriture sur lequel le service de données écrit le flux de données reçues. |
Création du service de données en continu
Pour donner au runtime Services de données WCF accès à l'implémentation de IDataServiceStreamProvider et IDataServiceStreamProvider2, le service de données que vous créez doit également implémenter l'interface IServiceProvider. L'exemple de code suivant illustre l'implémentation de la méthode GetService pour retourner une instance de classe PhotoServiceStreamProvider qui implémente IDataServiceStreamProvider et IDataServiceStreamProvider2.
Partial Public Class PhotoData
Inherits DataService(Of PhotoDataContainer)
Implements IServiceProvider
' This method is called only once to initialize service-wide policies.
Public Shared Sub InitializeService(ByVal config As DataServiceConfiguration)
config.SetEntitySetAccessRule("PhotoInfo", _
EntitySetRights.ReadMultiple Or _
EntitySetRights.ReadSingle Or _
EntitySetRights.AllWrite)
' Named streams require version 3 of the OData protocol.
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3
End Sub
#Region "IServiceProvider Members"
Public Function GetService(ByVal serviceType As Type) As Object _
Implements IServiceProvider.GetService
If serviceType Is GetType(IDataServiceStreamProvider) _
Or serviceType Is GetType(IDataServiceStreamProvider2) Then
Return New PhotoServiceStreamProvider(Me.CurrentDataSource)
End If
Return Nothing
End Function
#End Region
End Class
public partial class PhotoData : DataService<PhotoDataContainer>, IServiceProvider
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("PhotoInfo",
EntitySetRights.ReadMultiple |
EntitySetRights.ReadSingle |
EntitySetRights.AllWrite);
// Named resource streams require version 3 of the OData protocol.
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
public object GetService(Type serviceType)
{
if (serviceType == typeof(IDataServiceStreamProvider2))
{
// Return the stream provider to the data service.
return new PhotoServiceStreamProvider(this.CurrentDataSource);
}
return null;
}
}
Pour plus d'informations générales sur la création d'un service de données, consultez Configuration du service de données (WCF Data Services).
Activation de flux binaires volumineux dans l'environnement d'hébergement
Lorsque vous créez un service de données dans une application Web, ASP.NET, Windows Communication Foundation (WCF) est utilisé pour fournir l'implémentation du protocole HTTP. Par défaut, WCF limite la taille des messages HTTP à 65 kilo-octets. Pour pouvoir transmettre en continu des données binaires volumineuses depuis et vers le service de données, vous devez également configurer l'application Web pour autoriser les fichiers binaires volumineux et utiliser des flux de données pour le transfert. Pour cela, ajoutez les éléments suivants dans l'élément <configuration /> du fichier Web.config de l'application :
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<!-- The name of the service -->
<service name="PhotoService.PhotoData">
<!--you can leave the address blank or specify your end point URI-->
<endpoint binding="webHttpBinding" bindingConfiguration="higherMessageSize"
contract="System.Data.Services.IRequestHandler"></endpoint>
</service>
</services>
<bindings>
<webHttpBinding>
<!-- configure the maxReceivedMessageSize value to suit the max size of
the request (in bytes) you want the service to receive-->
<binding name="higherMessageSize" transferMode="Streamed"
maxReceivedMessageSize="2147483647"/>
</webHttpBinding>
</bindings>
</system.serviceModel>
Notes
Vous devez utiliser un mode de transfert TransferMode.Streamed pour vous assurer que les données binaires des messages de demande et de réponse sont transmis en continu et non mis en mémoire tampon par WCF.
Pour plus d'informations, consultez Streaming Message Transfer et Transport Quotas.
Par défaut, Internet Information Services (IIS) limite également la taille des demandes à 4 Mo. Pour activer votre service de données pour recevoir des flux supérieurs à 4 Mo lors d'une exécution sur IIS, vous devez également définir l'attribut maxRequestLength de l'httpRuntime Element dans la section de configuration <system.web />, comme indiqué dans l'exemple suivant :
<system.web>
<!-- maxRequestLength (in KB): default=4000 (4MB); max size=2048MB. -->
<httpRuntime maxRequestLength="2000000"/>
</system.web>
Utilisation de flux de données en continu dans une application cliente
Vous pouvez accéder à un flux de données binaires directement à l'aide de l'un des URI suivants :
Flux de ressource multimédia :
https://localhost/PhotoService/PhotoData.svc/PhotoInfo(1)/$value
Flux de ressource nommé :
https://localhost/PhotoService/PhotoData.svc/PhotoInfo(1)/Thumbnail
La bibliothèque cliente Services de données WCF vous permet de récupérer et de mettre à jour ces ressources exposées sous la forme de flux binaires sur le client. Pour plus d'informations, consultez Utilisation de données binaires (WCF Data Services).
Remarques sur l'utilisation d'un fournisseur de diffusion en continu
Les éléments suivants sont à prendre en compte lorsque vous implémentez un fournisseur de diffusion en continu et lorsque vous accédez aux ressources multimédias d'un service de données.
Vous devez implémenter l'interface IDataServiceStreamProvider en prenant en charge la ressource multimédia ou la ressource nommée des flux. Pour prendre en charge les flux de ressources nommés, vous devez également implémenter l'interface IDataServiceStreamProvider2.
Lorsque vous définissez un flux de ressources nommées qui appartient à une entrée de lien multimédia, l'entité définie dans le modèle de données ne doit pas inclure une propriété portant le même nom que le flux de données.
Les demandes MERGE ne sont pas prises en charge pour les ressources multimédias. Utilisez une demande PUT pour modifier la ressource multimédia d'une entité existante.
Une requête POST ne peut pas être utilisée pour créer une entrée de lien média. Vous devez plutôt émettre une requête POST pour créer une ressource multimédia. Le service de données crée alors une entrée de lien média avec les valeurs par défaut. Cette nouvelle entité peut être mise à jour par une demande MERGE ou PUT ultérieure. Vous pouvez également envisager de mettre en cache l'entité et de faire des mises à jour dans le dispositif de nettoyage, par exemple d'affecter à la propriété la valeur de l'en-tête Slug dans la requête POST.
Lorsqu'une requête POST est reçue, le service de données appelle la méthode GetWriteStream pour créer la ressource multimédia avant d'appeler la méthode SaveChanges pour créer l'entrée de lien média.
Une implémentation de la méthode GetWriteStream ne doit pas retourner d'objet MemoryStream. Si vous utilisez ce type de flux de données, des problèmes de ressource mémoire se produiront lorsque le service recevra des flux de données très volumineux.
Voici des éléments à prendre en compte lors du stockage de ressources multimédias dans une base de données :
Une propriété binaire qui est une ressource multimédia ne doit pas être incluse dans le modèle de données. Toutes les propriétés exposées dans un modèle de données sont retournées dans l'entrée dans un flux de réponse.
Pour améliorer les performances avec des flux binaires volumineux, nous vous conseillons de créer une classe de flux de données personnalisée pour stocker les données binaires dans la base de données. Cette classe est retournée par votre implémentation de GetWriteStream et transmet les données binaires à la base de données par segments. Pour une base de données SQL Server, nous vous conseillons d'utiliser un FILESTREAM pour diffuser les données en continu dans la base de données lorsque la taille des données binaires est supérieure à 1 Mo.
Vérifiez que votre base de données est conçue pour stocker les flux de données binaires volumineux qui seront reçus par votre service de données.
Lorsqu'un client envoie une requête POST pour insérer une entrée de lien média avec une ressource multimédia dans une demande unique, la méthode GetWriteStream est appelée pour obtenir le flux de données avant que le service de données n'insère la nouvelle entité dans la base de données. Une implémentation de fournisseur de diffusion en continu doit pouvoir gérer ce comportement de service de données. Envisagez d'utiliser une table de données distincte pour stocker les données binaires ou stockez le flux de données dans un fichier jusqu'à ce que l'entité soit insérée dans la base de données.
Lorsque vous implémentez les méthodes DeleteStream, GetReadStreamou GetWriteStream, vous devez utiliser les valeurs eTag et Content-Type fournies comme paramètres de méthode. Ne définissez pas d'en-tête eTag ou Content-Type dans votre implémentation de fournisseur IDataServiceStreamProvider.
Par défaut, le client transmet les flux binaires volumineux à l'aide d'un encodage de transfert HTTP segmenté. Étant donné que le serveur de développement ASP.NET ne prend pas en charge ce type d'encodage, vous ne pouvez pas utiliser ce serveur Web pour héberger un service de données en continu qui doit accepter des flux binaires volumineux. Pour plus d'informations sur le serveur de développement ASP.NET, consultez Web Servers in Visual Web Developer.
Conditions requises pour le contrôle de version
Le fournisseur de diffusion en continu respecte les conditions requises pour le contrôle de version de protocole OData suivantes :
Le fournisseur de diffusion en continu requiert que le client et le service de données prennent en charge les versions 2.0 et ultérieures du protocole OData .
La prise en charge des flux nommés requiert que le client et le service de données prennent en charge les versions 3.0 et ultérieures du protocole OData.
Pour plus d'informations, consultez Contrôle de version d'un service de données (WCF Data Services).
Voir aussi
Concepts
Fournisseurs de services de données (WCF Data Services)
Fournisseurs de services de données personnalisés (WCF Data Services)