tags:

views:

225

answers:

1

Dear all,

My wcf client gives me the following error when attempting to download a file from the service: "An error occurred while receiving the HTTP response to http://mypc-pc/xmlLoadService/Service.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details."

The code being executed is this:

 System.IO.FileStream fs;
        try
        {
            fs = (System.IO.FileStream)client.Download(@"C:\UploadedFiles\Test.txt");
            byte[] arr = new byte[fs.Length];
            int read;
            do
            {
                read = fs.Read(arr, 0, arr.Length);

            } while (read != arr.Length);

            Console.WriteLine(ASCIIEncoding.ASCII.GetString(arr));
            Console.ReadLine();
        }

This is my web.config config:

<bindings>
   <basicHttpBinding>
       <binding name="basicHTTP" receiveTimeout="00:10:00" 
                sendTimeout="00:03:00" closeTimeout="00:10:00" 
                openTimeout="00:03:00" messageEncoding="Mtom" 
                maxBufferSize="100000" maxReceivedMessageSize="100000" 
                transferMode="Buffered">
       </binding>
   </basicHttpBinding>
</bindings>
<services>
   <service behaviorConfiguration="ServiceBehavior" name="Service">
       <endpoint address="" binding="wsHttpBinding" contract="IService">
           <identity>
               <dns value="localhost" />
           </identity>
       </endpoint>
       <endpoint address="mex" binding="mexHttpBinding" 
                 contract="IMetadataExchange" />
   </service>
   <service behaviorConfiguration="mexBehavior" 
            name="LoadXMLService.XMLOperations">
        <endpoint address="" 
                  binding="basicHttpBinding" 
                  bindingConfiguration="basicHTTP" 
                  behaviorConfiguration="" 
                  contract="LoadXMLService.IxmlLoad" />
   </service>
</services>

It fails where the 'download' function is being called on the server.

HELP me please?

Thanks in advance.

T

UPDATE: From what I understand from the trace log, the file is not being opened at the service end.

This is the code that is supposed to open the file, and it does not throw any exceptions when going through it step by step:

  public Stream Download( string path )
    {
        try
        {
            using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {

                return stream;
            }
        }
        catch (Exception ex)
        {
            string error = ex.Message;

            return null;
        }
    }

The file is a text file with only one line inside it. Here's the trace log:

524340 3 0 2 TONY-PC http://msdn.microsoft.com/en-GB/library/System.ServiceModel.ServiceOperationExceptionOnReply.aspx Replying to an operation threw a exception. b986c3da-11-128991431145070000 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime/48562646 System.ObjectDisposedException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Cannot access a closed file. at System.IO.__Error.FileNotOpen() at System.IO.FileStream.Read(Byte[] array, Int32 offset, Int32 count) at System.Xml.XmlMtomWriter.WriteXOPBinaryParts() at System.Xml.XmlMtomWriter.WriteEndElement() at System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer) at System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer) at System.ServiceModel.Channels.MtomMessageEncoder.WriteMessage(Message message, Stream stream, String startInfo, String boundary, String startUri, Boolean writeMessageHeaders) at System.ServiceModel.Channels.MtomMessageEncoder.WriteMessage(Message message, Stream stream, String boundary) at System.ServiceModel.Channels.HttpOutput.WriteStreamedMessage(TimeSpan timeout) at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout) at System.ServiceModel.Channels.HttpRequestContext.OnReply(Message message, TimeSpan timeout) at System.ServiceModel.Activation.HostedHttpContext.OnReply(Message message, TimeSpan timeout) at System.ServiceModel.Channels.RequestContextBase.Reply(Message message, TimeSpan timeout) at System.ServiceModel.Channels.RequestContextBase.Reply(Message message) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc& rpc) System.ObjectDisposedException: Cannot access a closed file. at System.IO.__Error.FileNotOpen() at System.IO.FileStream.Read(Byte[] array, Int32 offset, Int32 count) at System.Xml.XmlMtomWriter.WriteXOPBinaryParts() at System.Xml.XmlMtomWriter.WriteEndElement() at System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer) at System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer) at System.ServiceModel.Channels.MtomMessageEncoder.WriteMessage(Message message, Stream stream, String startInfo, String boundary, String startUri, Boolean writeMessageHeaders) at System.ServiceModel.Channels.MtomMessageEncoder.WriteMessage(Message message, Stream stream, String boundary) at System.ServiceModel.Channels.HttpOutput.WriteStreamedMessage(TimeSpan timeout) at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout) at System.ServiceModel.Channels.HttpRequestContext.OnReply(Message message, TimeSpan timeout) at System.ServiceModel.Activation.HostedHttpContext.OnReply(Message message, TimeSpan timeout) at System.ServiceModel.Channels.RequestContextBase.Reply(Message message, TimeSpan timeout) at System.ServiceModel.Channels.RequestContextBase.Reply(Message message) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc& rpc) 921505170062 at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace() at System.Diagnostics.TraceEventCache.get_Callstack() at System.Diagnostics.XmlWriterTraceListener.WriteFooter(TraceEventCache eventCache) at System.Diagnostics.XmlWriterTraceListener.TraceData(TraceEventCache eventCache, String source, TraceEventType eventType, Int32 id, Object data) at System.Diagnostics.TraceSource.TraceData(TraceEventType eventType, Int32 id, Object data) at System.ServiceModel.Diagnostics.DiagnosticTrace.TraceEvent(TraceEventType type, TraceCode code, String description, TraceRecord trace, Exception exception, Object source) at System.ServiceModel.Diagnostics.TraceUtility.TraceEvent(TraceEventType severity, TraceCode traceCode, TraceRecord extendedData, Object source, Exception exception) at System.ServiceModel.Diagnostics.TraceUtility.TraceEvent(TraceEventType severity, TraceCode traceCode, Object source, Exception exception) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessageCleanup(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Dispatch(MessageRpc& rpc, Boolean isOperationContextSet) at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext) at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext) at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result) at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result) at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously) at System.ServiceModel.Channels.InputQueue1.AsyncQueueReader.Set(Item item) at System.ServiceModel.Channels.InputQueue1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread) at System.ServiceModel.Channels.InputQueue1.EnqueueAndDispatch(T item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread) at System.ServiceModel.Channels.InputQueueChannel1.EnqueueAndDispatch(TDisposable item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread) at System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread) at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback) at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result) at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest() at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest() at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state) at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2() at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke() at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks() at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state) at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped) at System.Threading.IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped pOVERLAP)

+1  A: 

Since you appear to be using streamed responses - how does your config look like? Do you have something like this in your client config??

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="FileTransferBinding"
                  transferMode="StreamedResponse" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint name="DefaultEndpoint"
                address="....."
                binding="basicHttpBinding"
                bindingConfiguration="FileTransferBinding"
                contract="IYourContract" />
    </client>
  </system.serviceModel>
  • a BindingConfiguration which has a transferMode=Streamed or transferMode=StreamResponse
  • a client endpoint which has a binding=basicHttpBinding and a bindingConfiguration=FileTransferBinding (where the name of the binding configuration is the same as above in the declaration of the binding config)

That's the absolute bare minimum you should have - but without that crucial information provided, it's just guesswork.....

UPDATE: Your problem most like is the fact that you don't have transferMode="StreamResponse" in your binding configuration. Only if you have this setting will you be able to read a Stream as the response from the service call!

UPDATE 2: if you continue to have trouble, I'd strongly suggest you configure and turn on WCF tracing - add this snippet to your client config:

<configuration>
   <system.diagnostics>
      <sources>
            <source name="System.ServiceModel" 
                    switchValue="Information, ActivityTracing"
                    propagateActivity="true">
            <listeners>
               <add name="traceListener" 
                   type="System.Diagnostics.XmlWriterTraceListener" 
                   initializeData= "c:\log\Traces.svclog" />
            </listeners>
         </source>
      </sources>
   </system.diagnostics>
</configuration>

It will write trace information to the file C:\log\traces.svclog (make sure the directory exists), and you can inspect those with the Service Trace Viewer (SvcTraceViewer.exe in your C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\)

Check out the MSDN docs on how to configure and setup WCF tracing for more information.

UPDATE 3: since you want to actually RETURN the stream (and not close it on the server), you should not put your stream code into a using() {...} block!

Try this instead:

public Stream Download( string path )
{
    try
    {
        FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
        return stream;
    }
    catch (Exception ex)
    {
        string error = ex.Message;
        return null;
    }
}

You need to open the stream on the server, and leave it open and return it. It's the client's job to ensure it will be closed after the client's done reading it.

Putting that code in a using() {....} block is best practice in general, but doesn't work in this "server opens stream and returns it to client" scenario.

Marc

marc_s
I posted my web.config config for you. Hope that helps.
Tony
So I changed the config to StreamedResponse and now I get this error:"An error (Unable to read data from the transport connection: The connection was closed.) occurred while transmitting data over the HTTP channel."Could that be something with the timouts on the channel?
Tony
You should check out WCF tracing and let it trace error messages into a file and examine that!
marc_s
Thank you marc. I have now got a trace log. I will look up the Event ID of the error I get, which is: 131075
Tony