2016-05-31 3 views
2

У меня очень мало опыта работы в WCF, и я хочу загрузить файл на сервер с клиентской машины через службу WCF (с помощью потоковой передачи). Я прочитал несколько тем и написал простой пример сам, но, к сожалению, не работаетC# stream wcf upload file

Это код интерфейса:

[ServiceContract] 
public interface IService1 
{  
    [OperationContract] 
    string UpStream(FileStream inStream);   
} 

Это реализация:

public string UpStream(FileStream inStream) 
    { 
     using(StreamReader sr = new StreamReader(inStream)) 
     { 
      var recievedText = sr.ReadToEnd(); 

      if (recievedText != "") 
      { 
       return recievedText; 
      } 
      else 
      { 
       return "nothing"; 
      } 
     }   
    } 

Это клиентский код :

private void button3_Click(object sender, EventArgs e) 
    { 
     service2.Service1Client sc = new service2.Service1Client(); 

     OpenFileDialog opf = new OpenFileDialog(); 
     opf.ShowDialog(); 
     if (opf.FileName != "") 
     { 
      using (FileStream inStream = File.Open(opf.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))   
      {              
        MessageBox.Show(sc.UpStream(inStream)); 
      } 
     } 


    } 

Я думаю, что проблема должна быть где-то в файле конфигурации или в потоке. При запуске программы клиента и вызвать метод вверх по течению, WCF-сервис ПОЛУЧАТЬ пустой поток

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <services /> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="NewBinding0" maxBufferPoolSize="52428800" maxBufferSize="65536000" 
      maxReceivedMessageSize="6553600000" transferMode="Streamed" 
      useDefaultWebProxy="true" /> 
     </basicHttpBinding> 
    </bindings> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior>  
      <serviceMetadata httpGetEnabled="true"/>  
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <directoryBrowse enabled="true"/> 
    </system.webServer> 
</configuration> 

Если кто-то может помочь мне с решением моей проблемы, я буду очень благодарен

+0

Я попытался воспроизвести, но когда я сделал FileStream был нулевым. Когда я изменил тип на обычный поток, он сработал. – Ykok

ответ

1

Streaming очень полезно, но немного сложнее, чтобы получить голову вокруг

в этой статье MSDN предоставляет множество деталей https://msdn.microsoft.com/en-us/library/ms733742%28v=vs.110%29.aspx

но не делает некоторые детали очень четкие

во-первых, вам необходимо передавать сообщения, а не параметры

это будет выглядеть что-то вроде

[MessageContract] 
public class DataTransfer 
{ 
    [MessageHeader(MustUnderstand = true)] 
    public DataContract.HandShake Handshake { get; set; } 
    [MessageBodyMember(Order = 1)] 
    public Stream Data { get; set; } 
    //notice that it is using the default stream not a file stream, this is because the filestream you pass in has to be changed to a network stream to be sent via WCF 
} 

где класс Рукопожатие обеспечивает параметры, необходимые для включения вместе с потоком

public SaveResponse SaveData(DataTransfer request) 
{ 
    using (var stream = new System.IO.MemoryStream()) 
    { 
     request.Data.CopyTo(stream); 
     stream.Position = 0; 
     //this is because you have less control of a stream over a network than one held locally, so by copying from the network to a local stream you then have more control 

следующий конфигурация: вы должны настроить для потоковой передачи на сервере и клиент

который требует что-то вроде этого

<bindings> 
    <basicHttpBinding> 
    <binding name="ServiceBinding" transferMode="Streamed" messageEncoding="Mtom" maxReceivedMessageSize="67108864" maxBufferSize="65536" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"> 
    </binding> 
    </basicHttpBinding> 
</bindings> 
+0

Большое спасибо! Я изменил FileStream на Stream и добавил привязку к клиентскому приложению. После этого все начало работать отлично – avidnov

+0

Вы можете использовать Stream как параметр и строку как возвращаемый тип. Для этого вам не нужно определять контракт с сообщением. – Ykok

+1

true, но только в том случае, если все сообщение является потоком, чтобы сделать поток с любой информацией, тогда сообщение требуется, и как отправка полностью анонимного потока может быть опасным, тогда его лучшая практика включать некоторую информацию о потоке, такую ​​как хэш-код , длина потока и т. – MikeT