WCF: en utilisant le streaming avec des contrats de message
-
20-09-2019 - |
Question
Je suis en train d'utiliser la WCF en continu avec des contrats de message, car j'ai besoin des paramètres supplémentaires à côté du cours d'eau lui-même.
En fait, je suis en train de créer un service de téléchargement et fichier à télécharger, avec une certaine logique supplémentaire sur le dessus.
Malheureusement, lorsque je tente de frapper le service du navigateur pour vérifier que tout va bien, je reçois l'erreur suivante:
Erreur de serveur dans l'application '/'. Opération « UploadFile » dans le contrat « IFileTransferService » utilise un MessageContract qui a des en-têtes SOAP. têtes SOAP ne sont pas pris en charge par le MessageVersion Aucun.
Malheureusement googler il n'a donné aucun résultat significatif qui m'a aidé. Pouvez-vous les gars ont me aider? Voici les détails du service (j'ai retiré la partie de téléchargement pour des raisons 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>
UPDATE : la lecture de la documentation en ligne, il semble que le streaming avec MessageContracts devrait en effet être possible. Se référer par exemple à MSDN ( grandes quantités de données et Streaming):
Modèle de programmation pour les transferts streamées
Le modèle de programmation pour le streaming est simple. pour recevoir les données transmises en continu, spécifient une opération contrat qui a un seul flux paramètre d'entrée typé. pour revenir les données transmises en continu, le retour d'un flux référence. [...] Cette règle de la même applique aux contrats de message. Comme montré dans le contrat de message suivant, vous ne peut avoir qu'un seul membre du corps votre contrat de message qui est courant. Si vous voulez communiquer plus d'informations avec les flux, ces informations doivent être des en-têtes de message. le corps du message est exclusivement réservé pour la teneur en cours d'eau.
[MessageContract]
public class UploadStreamMessage
{
[MessageHeader]
public string appRef;
[MessageBodyMember]
public Stream data;
}
Je l'ai aussi vu les messages de blog des gens de télécharger des services accomplissant de fichiers et télécharger très semblable à ce que je suis en train de mettre en place (par exemple ).
MISE À JOUR 2 Je l'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. Toute idée?
Mettre à Jour 3 Voir ma réponse.
La solution
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
(!).
Dans le basicHttpBinding final était parfaitement bien, je ne l'ai pas besoin de recourir à une liaison personnalisée.
Version originale (mauvaise):
<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>
Nouvelle version (fixe):
<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: Transfert de fichiers avec WCF
Autres conseils
Avez-vous besoin en continu (à savoir le transfert de quantités de données humonguous) à la fois sur la demande et la réponse? Ou tout simplement la réponse (généralement: le téléchargement d'un fichier ou d'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 paramètre « Streamed » coulera dans les deux sens - à la fois la demande d'aller au serveur, ainsi que la réponse du serveur, sera diffusé. Plus souvent qu'autrement, ce n'est pas le scénario idéal.
Marc
Je suis l'erreur après avoir utilisé le modèle « WCF Data Service » pour générer le fichier svc au lieu du modèle 'service WCF. Correction du fichier hôte de service la question a été résolu.