2009-08-27 10 views
20

Estoy tratando de usar la transmisión WCF con Contratos de mensajes porque necesito parámetros adicionales junto a la transmisión en sí.WCF: utilizando transmisión por secuencias con Message Contracts

Básicamente estoy creando un servicio de carga y descarga de archivos, con alguna lógica adicional en la parte superior.

Por desgracia, cuando trato de golpear el servicio desde el navegador para comprobar que todo está bien, me sale el siguiente error:

Error de servidor en la aplicación '/'. La operación 'UploadFile' en el contrato 'IFileTransferService' usa un MessageContract que tiene encabezados SOAP. Los encabezados SOAP no son compatibles con None MessageVersion.

Desafortunadamente, buscar en Google no arrojó ningún resultado significativo que me haya ayudado. ¿Pueden ayudarme? Aquí los detalles del servicio (he eliminado la parte de descarga por razones de espacio).

[ServiceContract(Namespace = "http://www.acme.org/2009/04")] 
public interface IFileTransferService 
{ 
    [OperationContract(Action = "UploadFile")] 
    void UploadFile(FileUploadMessage request); 
} 

[MessageContract] 
public class FileUploadMessage 
{ 
    [MessageHeader(MustUnderstand = true)] 
    public FileMetaData Metadata { get; set; } 

    [MessageBodyMember(Order = 1)] 
    public Stream FileByteStream { get; set; } 
} 

[DataContract(Namespace = "http://schemas.acme.org/2009/04")] 
public class FileMetaData 
{ 
    [DataMember(Name="FileType", Order=0, IsRequired=true)] 
    public FileTypeEnum fileType; 

    [DataMember(Name="localFilename", Order=1, IsRequired=false)] 
    public string localFileName; 

    [DataMember(Name = "remoteFilename", Order = 2, IsRequired = false)] 
    public string remoteFileName; 
} 

He intentado utilizar tanto BasicHttpBinding y una unión con el efecto positivo no customhttp:

<customBinding> 
    <binding name="customHttpBindingStream"> 
     <textMessageEncoding messageVersion="Soap12" /> 
     <httpTransport transferMode="Streamed" maxReceivedMessageSize="2147483647"/> 
    </binding> 
</customBinding> 

ACTUALIZACIÓN: la lectura de la documentación en línea, parece que el streaming con MessageContracts de hecho debe ser posible. Se refieren por ejemplo a MSDN (Large Data and Streaming):

Programming Model for Streamed Transfers

The programming model for streaming is straightforward. For receiving streamed data, specify an operation contract that has a single Stream typed input parameter. For returning streamed data, return a Stream reference. [...] This rule similarly applies to message contracts. As shown in the following message contract, you can have only a single body member in your message contract that is a stream. If you want to communicate additional information with the stream, this information must be a carried in message headers. The message body is exclusively reserved for the stream content.

[MessageContract] 
public class UploadStreamMessage 
{ 
    [MessageHeader] 
    public string appRef; 
    [MessageBodyMember] 
    public Stream data; 
} 

También he visto entradas del blog de la gente llevar a cabo los servicios de archivo de carga y descarga muy similar a lo que estoy tratando de poner juntos (por ejemplo here).

ACTUALIZACIÓN 2 que han intentado crear una pequeña consola y auto aloja el servicio con una basicHttpBinding y no funciona como un encanto. Estoy empezando a creer que el problema podría ser el alojamiento en IIS. ¿Alguna idea?

ACTUALIZACIÓN 3 Ver mi propia respuesta.

+0

Creo que 'Order = 1' es redundante en el atributo' MessageBodyMember' ya que solo tiene un elemento de cuerpo –

Respuesta

8

finalmente descubierto lo que era el error: no tenía nada que ver con las versiones de jabón, arroyos, etc ... Sólo mispelled el nombre de mi propio servicio, utilizando FileTransfer en lugar de (!) FileTransferService.

Al final basicHttpBinding estaba perfectamente bien, no tuve que recurrir a un encuadernado personalizado.

original (malo) versión:

<service 
    behaviorConfiguration="serviceBehavior" 
    name="Acme.Service.FileTransfer"> 
    <endpoint address="" 
     name="basicHttpStream" 
     binding="basicHttpBinding" 
     bindingConfiguration="httpLargeMessageStream" 
     contract="Acme.Service.IFileTransferService" /> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
</service> 

Nueva (fijo) Versión:

<service 
    behaviorConfiguration="serviceBehavior" 
    name="Acme.Service.FileTransferService"> 
    <endpoint address="" 
     name="basicHttpStream" 
     binding="basicHttpBinding" 
     bindingConfiguration="httpLargeMessageStream" 
     contract="Acme.Service.IFileTransferService" /> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
</service> 

Todavía no se puede decir que el mensaje de error fue útil para cualquier forma de comprender lo que estaba pasando aquí ...

Si está interesado en el servicio completo, puede encontrar más detalles en mi blog en el siguiente enlace: File Transfer with WCF

2

¿Necesita transmisión (es decir, transferencia de cantidades de datos en masa) tanto en la solicitud como en la respuesta? ¿O solo en la respuesta (típicamente: descargar un archivo o un gran conjunto de datos)?

Si necesita sólo en la respuesta, usted debe tratar de establecer el transferMode a "StreamedResponse":

<customBinding> 
    <binding name="customHttpBindingStream"> 
     <textMessageEncoding messageVersion="Soap12" /> 
     <httpTransport transferMode="StreamedResponse" 
         maxReceivedMessageSize="2147483647"/> 
    </binding> 
</customBinding> 

El ajuste "streaming" fluirá en ambos sentidos - tanto la solicitud de ir al servidor, como se así como la respuesta del servidor, será transmitida. La mayoría de las veces, ese no es el escenario ideal.

Marc

+0

Hola Marc, como mencioné en mi pregunta, estoy creando un servicio de archivos que permite subir y descargar archivos . Por lo tanto, necesito poder transmitir en ambos sentidos. ¿Crees que esto tiene algo que ver con el error que estoy experimentando? –

+0

No estoy seguro - Nunca he visto la combinación de transmisión por secuencias con contratos de mensajes antes ..... y he visto casos en los que solo la descarga del servidor era grande (descarga de archivos) y la configuración del TransferMode a StreamedResponse me ayudó –

+0

Hace funciona si solo usa DataContract (sin la parte Contrato de mensaje) - solo para ver, para probar –

0

Recibí el error después de usar la plantilla 'WCF Data Service' para generar el archivo svc en lugar de la plantilla 'WCF Service'. Al corregir el archivo host del servicio, se solucionó el problema.

Cuestiones relacionadas