Compartir a través de


Proveedores de transmisión por secuencias (WCF Data Services)

Un servicio de datos puede exponer datos binarios de objetos grandes. Estos datos binarios pueden representar secuencias de vídeo y audio, imágenes, archivos de documento u otros tipos de medios binarios. Cuando una entidad del modelo de datos incluye una o más propiedades binarias, el servicio de datos devuelve estos datos binarios codificados en base 64 en la entrada de la fuente de respuesta. Dado que la carga y la serialización de datos binarios grandes de esta manera pueden afectar al rendimiento, Open Data Protocol (OData) define un mecanismo para recuperar datos binarios independientemente de la entidad a la que pertenezcan. Para ello, se separan los datos binarios de la entidad en uno o varios flujos de datos.

  • Recurso multimedia: los datos binarios que pertenecen a una entidad, como vídeo, audio, imagen u otro tipo de flujo de recursos multimedia.

  • Entrada de vínculo multimedia: entidad con una referencia a un flujo de recursos multimedia relacionado.

Con WCF Data Services , defina un flujo de recursos binarios implementando un proveedor de transmisión de datos por secuencias. La implementación del proveedor de transmisión por secuencias proporciona al servicio de datos la secuencia de recursos multimedia asociada con una entidad concreta como objeto Stream. Esta implementación permite que el servicio de datos acepte y devuelva los recursos multimedia a través del protocolo HTTP como flujos de datos binarios de un tipo MIME especificado.

La configuración de un servicio de datos para que admita la transmisión por secuencias de datos binarios requiere los siguientes pasos:

  1. Atribuya una o más entidades del modelo de datos como una entrada de vínculo multimedia. Estas entidades no deben incluir los datos binarios que se van a transmitir por secuencias. Las propiedades binarias de una entidad siempre se devuelven en la entrada como datos binarios codificados en base 64.

  2. Implemente la interfaz T:System.Data.Services.Providers.IDataServiceStreamProvider.

  3. Defina un servicio de datos que implemente la interfaz IServiceProvider. El servicio de datos usa la implementación del método GetService para acceder a la implementación del proveedor de transmisión de datos por secuencias. Este método devuelve la implementación del proveedor de transmisión por secuencias adecuado.

  4. Habilite flujos de mensajes grandes en la configuración de la aplicación web.

  5. Habilite el acceso a los recursos binarios en el servidor o en un origen de datos.

Los ejemplos de este tema se basan en un servicio de fotografías de transmisión por secuencias de ejemplo, que se describe con todo detalle en la entrada del blog relacionado con la parte 1 de la implementación de un proveedor de transmisión por secuencias de la serie de proveedores de transmisión por secuencias de servicios de datos. El código fuente de este servicio de ejemplo está disponible en la página de ejemplo del servicio de datos de fotografía de transmisión por secuencias de la galería de código de MSDN.

Definir una entrada de vínculo multimedia en el modelo de datos

El proveedor del origen de datos determina cómo se define una entidad como entrada de vínculo multimedia en el modelo de datos.

  • Proveedor de Entity Framework
    Para indicar que una entidad es una entrada de vínculo multimedia, agregue el atributo HasStream a la definición del tipo de entidad en el modelo conceptual, como en el siguiente ejemplo:

    <EntityType xmlns:m="https://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
                Name="PhotoInfo" m:HasStream="true">
      <Key>
        <PropertyRef Name="PhotoId" />
      </Key>
      <Property Name="PhotoId" Type="Int32" Nullable="false" 
                annotation:StoreGeneratedPattern="Identity" />
      <Property Name="FileName" Type="String" Nullable="false" />
      <Property Name="FileSize" Type="Int32" Nullable="true" />
      <Property Name="DateTaken" Type="DateTime" Nullable="true" />
      <Property Name="TakenBy" Type="String" Nullable="true" />
      <Property Name="DateAdded" Type="DateTime" Nullable="false" />
      <Property Name="Exposure" Type="PhotoData.Exposure" Nullable="false" />
      <Property Name="Dimensions" Type="PhotoData.Dimensions" Nullable="false" />
      <Property Name="DateModified" Type="DateTime" Nullable="false" />
      <Property Name="Comments" Type="String" MaxLength="Max" 
                FixedLength="false" Unicode="true" />
      <Property Name="ContentType" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
    </EntityType>
    

    También debe agregar el espacio de nombres xmlns:m=https://schemas.microsoft.com/ado/2007/08/dataservices/metadata a la entidad o a la raíz del archivo .edmx o del archivo .csdl que definen el modelo de datos.

    Para obtener un ejemplo de servicio de datos que usa el proveedor Entity Framework y expone un recurso multimedia, vea la entrada del blog relacionado con la parte 1 de la implementación de un proveedor de transmisión por secuencias de la serie de proveedores de transmisión por secuencias de servicios de datos.

  • Proveedor de reflexión
    Para indicar que una entidad es una entrada de vínculo multimedia, agregue el atributo HasStreamAttribute a la clase que define el tipo de entidad en el proveedor de reflexión.

Implementar la interfaz IDataServiceStreamProvider

Para crear un servicio de datos que admita flujos de datos binarios, debe implementar la interfaz IDataServiceStreamProvider. Esta implementación habilita el servicio de datos para devolver al cliente datos binarios como flujo y utilizar los datos binarios como flujo enviado desde el cliente. El servicio de datos crea una instancia de esta interfaz cuando sea necesario para acceder a los datos binarios como flujo. La interfaz IDataServiceStreamProvider especifica los siguientes miembros:

Nombre del miembro Descripción

DeleteStream

El servicio de datos invoca este método para eliminar el recurso multimedia correspondiente cuando se elimina su entrada de vínculo multimedia. Cuando se implementa IDataServiceStreamProvider, este método contiene el código que elimina el recurso multimedia asociado con la entrada de vínculo multimedia proporcionada.

GetReadStream

El servicio de datos invoca este método para devolver un recurso multimedia como un flujo. Cuando se implementa IDataServiceStreamProvider, este método contiene el código que proporciona un flujo que el servicio de datos utiliza para devolver el recurso multimedia que está asociado a la entrada de vínculo multimedia proporcionada.

GetReadStreamUri

El servicio de datos invoca este método para devolver el URI que se utiliza para solicitar el recurso multimedia de la entrada de vínculo multimedia. Este valor se usa para crear el atributo src en el elemento de contenido de la entrada de vínculo multimedia que se utiliza para solicitar el flujo de datos. Cuando este método devuelve null, el servicio de datos automáticamente determina el URI. Use este método cuando deba proporcionar clientes con acceso directo a datos binarios sin usar el proveedor de flujos.

GetStreamContentType

El servicio de datos invoca este método para devolver el valor Content-Type del recurso multimedia asociado con la entrada de vínculo multimedia especificada.

GetStreamETag

El servicio de datos invoca este método para devolver el objeto eTag del flujo de datos que está asociado con la entidad especificada. Este método se utiliza cuando se administra la simultaneidad de los datos binarios. Cuando este método devuelve null, el servicio de datos no realiza el seguimiento de la simultaneidad.

GetWriteStream

El servicio de datos invoca este método para obtener el flujo que se utiliza cuando se recibe el flujo enviado desde el cliente. Cuando implemente la interfaz IDataServiceStreamProvider, debe devolver un flujo grabable en el que el servicio de datos pueda escribir los datos del flujo recibidos.

ResolveType

Devuelve un nombre de tipo calificado con el espacio de nombres que representa el tipo que el motor en tiempo de ejecución del servicio de datos debe crear para la entrada de vínculo multimedia asociada al flujo de datos del recurso multimedia que se está insertando.

Crear el servicio de transmisión de datos por secuencias

Para proporcionar al motor de tiempo de ejecución de WCF Data Services acceso a la implementación de la interfaz IDataServiceStreamProvider, el servicio de datos que cree también debe implementar la interfaz IServiceProvider. En el siguiente ejemplo se muestra cómo implementar el método GetService para devolver una instancia de la clase PhotoServiceStreamProvider que implemente la interfaz IDataServiceStreamProvider.

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;
    }
}

Para obtener información general sobre cómo crear un servicio de datos, vea Configurar el servicio de datos (WCF Data Services).

Habilitar flujos binarios grandes en el entorno de hospedaje

Cuando cree un servicio de datos en una aplicación web de ASP.NET, se usa Windows Communication Foundation (WCF) para proporcionar la implementación del protocolo HTTP. De forma predeterminada, WCF limita el tamaño de los mensajes HTTP a solo 65K bytes. Para poder transmitir datos binarios grandes por secuencias al servicio de datos y desde él, debe configurar también la aplicación web para habilitar archivos binarios grandes y utilizar secuencias para la transferencia. Para ello, en el elemento <configuration /> del archivo Web.config de la aplicación agregue lo siguiente:

 <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>
Ee960144.note(es-es,VS.100).gifNota:
Debe usar un modo de transferencia del campo System.ServiceModel.TransferMode.Streamed para asegurarse de que los datos binarios en los mensajes de solicitud y respuesta se transfieran y que WCF no los almacene en búfer.

Para obtener más información, vea Streaming Message Transfer y Transport Quotas.

De forma predeterminada, Internet Information Services (IIS) también limita el tamaño de las respuestas a 4 MB. Para habilitar el servicio de datos con el fin de recibir flujos mayores que 4 MB cuando se ejecute en IIS, también debe establecer el atributo maxRequestLength del elemento httpRuntime Element de la sección de configuración de <system.web /> como se muestra en el siguiente ejemplo:

  <system.web>
      <!-- maxRequestLength (in KB): default=4000 (4MB); max size=2048MB. -->
      <httpRuntime maxRequestLength="2000000"/>
</system.web>

Usar flujos de datos en una aplicación cliente

La biblioteca cliente de WCF Data Services le permite recuperar y actualizar estos recursos expuestos como flujos binarios en el cliente. Para obtener más información, vea Trabajar con datos binarios (Servicios de datos de WCF).

Consideraciones para trabajar con un proveedor de transmisión por secuencias

A continuación se enumeran algunas de las consideraciones que debe tener en cuenta al implementar un proveedor de transmisiones por secuencias y al tener acceso a los recursos multimedia de un servicio de datos.

  • Los recursos multimedia no admiten solicitudes MERGE. Utilice una solicitud PUT para cambiar el recurso multimedia de una entidad existente.

  • Una solicitud POST no se puede utilizar para crear una entrada de vínculo multimedia. En su lugar, debe emitir una solicitud POST para crear un nuevo recurso multimedia y el servicio de datos creará una entrada de vínculo multimedia con los valores predeterminados. Una solicitud MERGE o PUT posterior puede actualizar esta nueva entidad. También puede considerar la opción de almacenar en memoria caché la entidad y realizar actualizaciones en el contenedor de elementos eliminados, como establecer el valor de propiedad en el valor del encabezado Slug en la solicitud POST.

  • Cuando se recibe una solicitud POST, el servicio de datos llama a GetWriteStream para crear el recurso multimedia antes de llamar a SaveChanges para crear la entrada de vínculo multimedia.

  • Una implementación de GetWriteStream no debe devolver un objeto MemoryStream. Cuando se utiliza este tipo de flujo, se producirán problemas de recursos de memoria cuando el servicio reciba flujos de datos muy grandes.

  • A continuación se enumeran algunas de las consideraciones que debe tener en cuenta al almacenar recursos multimedia en una base de datos:

    • En el modelo de datos no debe incluirse una propiedad binaria que sea un recurso multimedia. Todas las propiedades expuestas en un modelo de datos se devuelven en la entrada de una fuente de respuesta.

    • Para mejorar el rendimiento con un flujo binario grande, recomendamos crear una clase de flujo personalizado para almacenar datos binarios en la base de datos. La implementación de GetWriteStream devuelve esta clase y envía los datos binarios a la base de datos en fragmentos. En el caso de una base de datos de SQL Server, se recomienda usar un objeto FILESTREAM para transmitir los datos por secuencias a la base de datos cuando los datos binarios ocupen más de 1 MB.

    • Asegúrese de que la base de datos esté diseñada para almacenar los flujos binarios grandes que vaya a recibir el servicio de datos.

    • Cuando un cliente envía a una solicitud POST para insertar una entrada de vínculo multimedia con un recurso multimedia en una solicitud única, se llama a GetWriteStream para obtener el flujo antes de que el servicio de datos inserte la nueva entidad en la base de datos. Una implementación del proveedor de transmisiones por secuencias debe ser capaz de controlar este comportamiento del servicio de datos. Considere la opción de usar una tabla de datos independiente para almacenar los datos binarios o almacenar el flujo de datos en un archivo hasta que la entidad se haya insertado en la base de datos.

  • Cuando implemente los métodos DeleteStream, GetWriteStream o GetReadStream, debe utilizar el objeto eTag y los valores Content-Type y que se proporcionan como parámetros de método. No establezca el objeto eTag ni los encabezados Content-Type en la implementación del proveedor IDataServiceStreamProvider.

  • De forma predeterminada, el cliente envía secuencias binarias grandes mediante codificación de transferencia HTTP fragmentada. Dado que el servicio de desarrollo de ASP.NET no admite este tipo de codificación, no podrá usar este servidor web para hospedar los servicios de transmisión de datos por secuencias que deban aceptar flujos binarios grandes. Para obtener más información sobre el servidor de desarrollo de ASP.NET, vea Web Servers in Visual Web Developer.

Requisitos de control de versiones

El proveedor de transmisión por secuencias tiene los siguientes requisitos de control de versiones de OData :

  • El proveedor de transmisión por secuencias requiere que el servicio de datos admita la versión 2.0 del protocolo de OData y versiones posteriores.

Para obtener más información, vea Trabajar con varias versiones de WCF Data Services.

Vea también

Conceptos

Proveedores de servicios de datos (WCF Data Services)
Proveedores de servicios de datos personalizados (WCF Data Services)
Trabajar con datos binarios (Servicios de datos de WCF)