Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>it seemed strange to me that you would have the problems you mentioned, so I was curious and put together an implementation using your service contract. That one actually worked straight away. I don't actually know what went wrong in your case (it's not obvious), but let me just post a working solution here hoping that this will help you to solve your problem.</p> <p>Unfortunately, as I abandoned VB many years ago, I can only provide C# code. Hope that's alright.</p> <p><strong>Server Web.config (tested in IIS, with net.tcp binding):</strong></p> <pre><code> &lt;system.serviceModel&gt; &lt;bindings&gt; &lt;netTcpBinding&gt; &lt;binding transferMode="Streamed" maxReceivedMessageSize="1000000"&gt; &lt;security mode="None"/&gt; &lt;/binding&gt; &lt;/netTcpBinding&gt; &lt;/bindings&gt; &lt;services&gt; &lt;service name="ImageSystem.SVC.UploadService"&gt; &lt;endpoint address="" binding="netTcpBinding" contract="ImageSystem.SVC.IUploadService"&gt; &lt;/endpoint&gt; &lt;endpoint address="mex" kind="mexEndpoint" binding="mexTcpBinding"/&gt; &lt;/service&gt; &lt;/services&gt; &lt;behaviors&gt; &lt;serviceBehaviors&gt; &lt;behavior&gt; &lt;serviceMetadata httpGetEnabled="false"/&gt; &lt;serviceDebug includeExceptionDetailInFaults="true"/&gt; &lt;/behavior&gt; &lt;/serviceBehaviors&gt; &lt;/behaviors&gt; &lt;/system.serviceModel&gt; </code></pre> <p><strong>Client app.config (console test app):</strong></p> <pre><code>&lt;system.serviceModel&gt; &lt;bindings&gt; &lt;netTcpBinding&gt; &lt;binding transferMode="Streamed" maxReceivedMessageSize="1000000"&gt; &lt;security mode="None"/&gt; &lt;/binding&gt; &lt;/netTcpBinding&gt; &lt;/bindings&gt; &lt;client&gt; &lt;endpoint address="net.tcp://localhost/WcfService1/UploadService.svc" binding="netTcpBinding" contract="ImageServices.IUploadService" name="NetTcpBinding_IUploadService"&gt; &lt;/endpoint&gt; &lt;/client&gt; &lt;/system.serviceModel&gt; </code></pre> <p><strong>Service contract &amp; implementation:</strong></p> <pre><code>[ServiceContract(Namespace="urn:ImageSystem")] public interface IUploadService { [OperationContract] ImageUpload UploadFile(ImageUpload file); } [MessageContract] public class ImageUpload { [MessageHeader] public long? ImageID { get; set; } [MessageBodyMember] public Stream Data; } public class UploadService : IUploadService { public ImageUpload UploadFile(ImageUpload file) { long length; using (var ms = new MemoryStream()) { file.Data.CopyTo(ms); length = ms.Length; } return new ImageUpload { ImageID = length, Data = new MemoryStream() }; } } </code></pre> <p>Test app:</p> <pre><code>private static readonly string imgPath = @"C:\Pictures\somepicture.jpg"; private static readonly EventWaitHandle waitHandle = new AutoResetEvent(false); static void Main() { long? result; using (var service = new ImageServices.UploadServiceClient("NetTcpBinding_IUploadService")) { var image = new ImageServices.ImageUpload(); using (var imgStream = File.OpenRead(imgPath)) { image.Data = imgStream; service.UploadFileCompleted += (sender, e) =&gt; { result = e.Result; if (e.Data != null) image.Data.Dispose(); waitHandle.Set(); }; service.UploadFileAsync(null, imgStream); waitHandle.WaitOne(); } } } </code></pre> <p>First of all, as you can see, the config files can be a lot simpler. Especially the large <code>BufferSize</code> value is not necessary. Then, with regard to the service contract, it's not clear to me why the <code>Upload</code> operation would receive AND return an <code>ImageUpload</code> message. In my implementation, I'm returning the uploaded file size in the <code>ImageID</code> parameter just for demo purposes, of course. I don't know what your reasoning behind that contract was, and what you actually would want to return.</p> <hr> <p>Actually, was just about to click "Send" when I had an idea why your code could have failed. In your test client, before you call <code>serviceClient.UploadFileAsync()</code>, add this line to your code: <code>ms.Seek(0, SeekOrigin.Begin)</code>. </p> <p>This resets the position of the MemoryStream back to its beginning. If you don't do that, the MemoryStream will be consumed only from its current position, which is its end - and which explains the Length = 0 of the stream received on the service side!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload