2011-07-06 4 views
4

J'ai un service WCF hébergé dans une application ASP.NET et essaie de télécharger un fichier à partir d'une autre application ASP.NET client en utilisant le mode de diffusion en continu. Je continue à obtenir l'erreur suivante:WCF question en streaming avec ASP.NET

The remote server returned an unexpected response: (400) Bad Request.

J'ai parcouru le net pour obtenir de l'aide, mais en vain.

Host Configuration:

<bindings> 
     <basicHttpBinding> 
     <binding name="FileTransferServicesBinding" 
      transferMode="Streamed" 
      messageEncoding="Mtom" 
      sendTimeout="01:05:00" 
      maxReceivedMessageSize="10067108864"> 
     </binding> 
     </basicHttpBinding> 
    </bindings> 
    <services> 
     <service behaviorConfiguration="FileTransferServiceBehavior" name="WebServiceHost.TransferService"> 
     <clear /> 
     <endpoint address="" binding="basicHttpBinding" 
      bindingConfiguration="FileTransferServicesBinding" contract="WebServiceHost.ITransferService"> 
      <identity> 
      <dns value="localhost"/> 
      <certificateReference storeName="My" storeLocation="LocalMachine" 
       x509FindType="FindBySubjectDistinguishedName" /> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"> 
     </endpoint> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:11291/TransferService.svc" /> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="FileTransferServiceBehavior"> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

Code des marchés:

[ServiceContract] 
public interface ITransferService 
{ 
    [OperationContract] 
    RemoteFileInfo DownloadFile(DownloadRequest request); 

    [OperationContract] 
    void UploadFile(RemoteFileInfo request); 

    [OperationContract] 
    string TestMethod(); 
} 

[MessageContract] 
public class DownloadRequest 
{ 
    [MessageBodyMember] 
    public string FileName; 
} 

[MessageContract] 
public class RemoteFileInfo : IDisposable 
{ 
    [MessageHeader(MustUnderstand = true)] 
    public string FileName; 

    [MessageHeader(MustUnderstand = true)] 
    public long Length; 

    [MessageBodyMember(Order = 1)] 
    public System.IO.Stream FileByteStream; 

    public void Dispose() 
    { 
     if (FileByteStream != null) 
     { 
      FileByteStream.Close(); 
      FileByteStream = null; 
     } 
    } 
} 

Configuration du client:

<bindings> 
    <basicHttpBinding> 
    <binding name="FileTransferServicesBinding" sendTimeout="01:05:00" 
     maxReceivedMessageSize="10067108864" messageEncoding="Mtom" 
     transferMode="Streamed" /> 
    </basicHttpBinding> 
</bindings> 
<client> 
    <endpoint address="http://localhost:11291/TransferService.svc/" 
     binding="basicHttpBinding" bindingConfiguration="FileTransferServicesBinding" 
     contract="TransferServiceReference.ITransferService" name="FileTransferService" 
     kind=""> 
    <identity> 
     <dns value="localhost" /> 
     <certificateReference storeName="My" storeLocation="LocalMachine" 
      x509FindType="FindBySubjectDistinguishedName" /> 
    </identity> 
    </endpoint> 
</client> 
<behaviors> 
    <serviceBehaviors> 
    <behavior> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="true" /> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 

Code client:

ITransferService clientUpload = new TransferServiceClient(); 

string datetime = clientUpload.TestMethod(); 

var uploadRequestInfo = new RemoteFileInfo(); 

uploadRequestInfo.FileName = FileUpload1.FileName; 
uploadRequestInfo.Length = FileUpload1.PostedFile.ContentLength; 
uploadRequestInfo.FileByteStream = FileUpload1.PostedFile.InputStream; 
clientUpload.UploadFile(uploadRequestInfo); 

L'appel échoue à la fois clientUpload.TestMethod() et clientUpload.UploadFile (uploadRequestInfo). Avec le mode buffered clientUpload.TestMethod() est invoqué, le problème est lié à la configuration en mode streaming.

Je serais reconnaissant de trouver une aide à ce sujet. Merci.

+0

Je ne vois rien de mal avec évidemment la config. Vous devrez peut-être [Activer le suivi] (http://msdn.microsoft.com/en-us/library/ms733025.aspx) sur le service pour creuser un peu plus loin – Smudge202

Répondre

2

est question dans votre contrat de données - public System.IO.Stream FileByteStream;. Retirer ce membre du contrat de données et utiliser stream dans votre contrat d'exploitation - par exemple:

[OperationContract(OneWay=true)] 
void UploadFile(RemoteFileInfo request, System.IO.Stream fileData); 

Cité de Large Data and Streaming (MSDN):

You should not be using System.IO.Stream derived types inside of data contracts. Stream data should be communicated using the streaming model, explained in the following "Streaming Data" section.

section Flux de données du même lien explique dans les détails.

est question dans votre contrat de données - public System.IO.Stream FileByteStream;. Retirer ce membre du contrat de données et utiliser stream dans votre contrat d'exploitation - par exemple:

[OperationContract(OneWay=true)] 
void UploadFile(RemoteFileInfo request, System.IO.Stream fileData); 

Cité de Large Data and Streaming (MSDN):

You should not be using System.IO.Stream derived types inside of data contracts. Stream data should be communicated using the streaming model, explained in the following "Streaming Data" section.

section Flux de données du même lien explique dans les détails.

EDIT: Toutes mes excuses - Je restrictions. Négligé Vous avez deux façons de résoudre le problème: utilisez MessageContract ou utilisez plusieurs opérations pour une même transaction. Exemple d'utilisation de multiples opérations sera

[OperationContract] 
Token UploadFile(System.IO.Stream fileData); 

[OperationContract] 
void ProvideFileInfo(Token token, RemoteFileInfo request); 

d'abord télécharger les données vers le serveur et le serveur émettra un jeton (par exemple guid), utilisez le jeton de mettre à jour d'autres informations.

façon plus préférable utilisera MessageContract et que vous avez déjà essayé.Quelques suggestions pour dépanner:

  1. Si vous l'hébergez dans IIS, vérifiez maxRequestLength dans web.config. Essayez de télécharger de petits fichiers. Au lieu d'utiliser directement le flux de la fenetre affichee, stockez-la sur le disque et utilisez le flot dessus. Le raisonnement en cours de requête http peut être nettoyé pendant le téléchargement.
  2. Utilisez un outil tel qu'un violoneur et voyez le message transmis par câble au service, qui peut donner un indice.
+0

Lorsque Stream est utilisé, il impose quelques restrictions: seulement un paramètre ou une valeur de retour du type de flux et si d'autres paramètres de type sont passés, l'erreur suivante est levée: "System.InvalidOperationException: Pour que la demande dans l'opération UploadFile soit un flux, l'opération doit avoir un seul paramètre dont le type est Stream. " – rageit

+0

Je dois aussi de transmettre des données relatives au flux, tels que la valeur d'identification et donc MessageContract a été utilisé. Encore une fois, lorsque MessageContract est utilisé sur un seul paramètre est autorisé. – rageit

+0

FYI: exception est levée lorsque UploadFile vide (demande RemoteFileInfo, System.IO.Stream fileData); est utilisé: "L'opération UploadFile a un paramètre ou un type de retour attribué à MessageContractAttribute Pour représenter le message de requête à l'aide d'un contrat de message, l'opération doit avoir un seul paramètre attribué à MessageContractAttribute. message de réponse à l'aide d'un contrat de message, la valeur de retour de l'opération doit être un type attribué à MessageContractAttribute et l'opération ne peut avoir aucun paramètre out ou ref. " – rageit