2009-08-27 6 views
20

J'essaie d'utiliser le streaming WCF avec les contrats de message, car j'ai besoin de paramètres supplémentaires à côté du flux lui-même. Fondamentalement, je crée un service de téléchargement et de téléchargement de fichiers, avec une logique supplémentaire sur le dessus.WCF: utilisation du streaming avec les contrats de message

Malheureusement, lorsque je tente de frapper le service du navigateur pour vérifier que tout va bien, je reçois l'erreur suivante:

Erreur du serveur dans l'application «/». L'opération 'UploadFile' dans le contrat 'IFileTransferService' utilise un MessageContract qui a des en-têtes SOAP. Les en-têtes SOAP ne sont pas pris en charge par None MessageVersion.

Malheureusement chercher sur ce site n'a donné aucun résultat significatif qui m'a aidé. Pouvez-vous m'aider? Voici les détails du service (j'ai supprimé la partie téléchargement pour raison d'espace).

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

J'ai essayé d'utiliser les deux BasicHttpBinding et un customhttp liant avec effet positif non:

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

MISE À JOUR: la lecture de la documentation, il semble que le streaming en ligne avec MessageContracts devrait en effet être possible. Voir par exemple: 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; 
} 

J'ai aussi vu les messages de blog des personnes accomplissant des services de téléchargement de fichiers et télécharger très semblable à ce que je suis en train de mettre en place (par exemple here).

MISE À JOUR 2 J'ai essayé de créer une petite console et le service d'hébergement auto avec un basicHttpBinding et là, il fonctionne comme un charme. Je commence à croire que le problème pourrait être l'hébergement sur IIS. Une idée?

MISE À JOUR 3 Voir ma propre réponse.

+0

Je crois que 'Order = 1' est redondant dans l'attribut' MessageBodyMember' car vous n'avez qu'un élément de corps –

Répondre

8

J'ai finalement découvert ce qui était l'erreur: il n'a rien à voir avec les versions de savon, des cours d'eau, etc ... Je viens mispelled le nom de mon propre service, en utilisant FileTransfer au lieu de (!) FileTransferService. En fin de compte basicHttpBinding était parfaitement bien, je n'avais pas besoin de recourir à une liaison personnalisée.

originale (mauvaise) Version:

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

Nouveau (fixe) Version:

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

Je ne peux pas dire que le message d'erreur utile de quelque façon de comprendre ce qui se passait ici ...

Si vous êtes intéressé par l'ensemble du service, vous pouvez trouver plus de détails sur mon blog à l'adresse suivante: File Transfer with WCF

2

Avez-vous besoin de la transmission en continu (c'est-à-dire le transfert de quantités de données non significatives) à la fois sur la demande et la réponse? Ou seulement sur la réponse (typiquement: télécharger un fichier ou un grand ensemble de données)?

Si vous avez besoin que la réponse, vous devriez essayer de régler le transferMode à « StreamedResponse »:

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

Le réglage « Streamed » coulera dans les deux sens - à la fois la demande d'aller au serveur, comme ainsi que la réponse du serveur, sera diffusée. Plus souvent qu'autrement, ce n'est pas le scénario idéal.

Marc

+0

Bonjour Marc, comme je l'ai mentionné dans ma question, je crée un service de fichiers qui permet à la fois le téléchargement et le téléchargement . Par conséquent, je dois être capable de diffuser les deux voies. Pensez-vous que cela a quelque chose à voir avec l'erreur que je vis? –

+0

Incertain - Je n'ai jamais vu la combinaison de streaming avec les contrats de message avant ..... et j'ai vu des cas où seul le téléchargement du serveur était grand (téléchargement de fichiers) et la définition du TransferMode à StreamedResponse aidé –

+0

cela fonctionne si vous utilisez seulement le DataContract (sans la partie contrat de message) - juste pour voir, pour tester –

0

J'ai reçu l'erreur après avoir utilisé le modèle 'WCF Data Service' pour générer le fichier svc au lieu du modèle 'WCF Service'. Correction du fichier hôte du service le problème a été résolu.

Questions connexes