internal void Write(Stream stream) { Stream responseMessageStream = null; Serializer responseSerializer = null; this.actualResponseMessageWhoseHeadersMayBeOverridden.SetStream(stream); try { switch (this.PayloadKind) { case ODataPayloadKind.BinaryValue: Debug.Assert( this.requestDescription.TargetKind == RequestTargetKind.OpenPropertyValue || this.requestDescription.TargetKind == RequestTargetKind.PrimitiveValue || this.requestDescription.TargetKind == RequestTargetKind.MediaResource, this.requestDescription.TargetKind + " is PrimitiveValue or OpenPropertyValue or StreamPropertyValue"); Debug.Assert(this.messageWriter == null, "No Message writer required for writing binary payload"); responseMessageStream = this.actualResponseMessageWhoseHeadersMayBeOverridden.GetStream(); BinarySerializer binarySerializer = new BinarySerializer(responseMessageStream); if (this.requestDescription.TargetKind == RequestTargetKind.MediaResource) { // If this.mediaResourceStream is null, we will set the status code to 204. // We would not get here on a WCF host, but on other hosts we would. Debug.Assert(this.requestDescription.IsNamedStream || this.mediaResourceStream != null, "this.mediaResourceStream cannot be null for MR request."); if (this.mediaResourceStream != null) { binarySerializer.WriteRequest(this.mediaResourceStream, this.service.StreamProvider.StreamBufferSize); } } else { binarySerializer.WriteRequest(this.queryResults.Current); } break; case ODataPayloadKind.Value: Debug.Assert( this.requestDescription.TargetKind == RequestTargetKind.OpenPropertyValue || this.requestDescription.TargetKind == RequestTargetKind.PrimitiveValue, this.requestDescription.TargetKind + " is PrimitiveValue or OpenPropertyValue"); TextSerializer textSerializer = new TextSerializer(this.messageWriter); textSerializer.WriteRequest(this.queryResults.Current); break; case ODataPayloadKind.ServiceDocument: Debug.Assert(this.requestDescription.TargetKind == RequestTargetKind.ServiceDirectory, "this.requestDescription.TargetKind == RequestTargetKind.ServiceDirectory"); ServiceDocumentSerializer serializer = new ServiceDocumentSerializer(this.messageWriter); serializer.WriteServiceDocument(this.service.Provider); break; case ODataPayloadKind.EntityReferenceLink: case ODataPayloadKind.EntityReferenceLinks: case ODataPayloadKind.Collection: case ODataPayloadKind.Property: Debug.Assert(this.requestDescription.TargetKind != RequestTargetKind.Resource || this.requestDescription.LinkUri, "this.requestDescription.TargetKind != RequestTargetKind.Resource || this.requestDescription.LinkUri"); NonEntitySerializer nonEntitySerializer = new NonEntitySerializer(this.requestDescription, this.AbsoluteServiceUri, this.service, this.messageWriter); responseSerializer = nonEntitySerializer; nonEntitySerializer.WriteRequest(this.queryResults); break; case ODataPayloadKind.Entry: case ODataPayloadKind.Feed: Debug.Assert(this.requestDescription.TargetKind == RequestTargetKind.Resource, "TargetKind " + this.requestDescription.TargetKind + " == Resource"); EntitySerializer entitySerializer = new EntitySerializer( this.requestDescription, this.AbsoluteServiceUri, this.service, this.service.OperationContext.ResponseMessage.GetHeader(XmlConstants.HttpResponseETag), this.messageWriter, this.contentFormat); responseSerializer = entitySerializer; entitySerializer.WriteRequest(this.queryResults); break; default: Debug.Assert(this.PayloadKind == ODataPayloadKind.MetadataDocument, "this.payloadKind == ODataPayloadKind.MetadataDocument"); Debug.Assert(this.requestDescription.TargetKind == RequestTargetKind.Metadata, "this.requestDescription.TargetKind == RequestTargetKind.Metadata"); this.messageWriter.WriteMetadataDocument(); break; } } catch (Exception exception) { if (!CommonUtil.IsCatchableExceptionType(exception)) { throw; } // Astoria-ODataLib-Integration: Astoria does not call flush before calling the IDataServiceHost.ProcessException method // If the request is for an entry/feed and the data source throws an error while these results are being enumerated and written, // the server doesn't flush the writer's stream before it calls HandleException and starts writing out the error. // To handle this case, we'll make the EntitySerializer expose a method that calls Flush on the underlying ODL writer instance. if (responseSerializer != null) { responseSerializer.Flush(); } ErrorHandler.HandleExceptionWhileWriting(this.service, exception, this.actualResponseMessageWhoseHeadersMayBeOverridden, this.messageWriter, this.encoding, stream, this.messageWriterBuilder); } finally { WebUtil.Dispose(this.messageWriter); WebUtil.Dispose(this.queryResults); WebUtil.Dispose(this.mediaResourceStream); // For batch operations, we need to dispose the stream obtained from calling // IODataResponseMessage.GetStream to signal that we are done with the message. if (responseMessageStream != null && this.actualResponseMessageWhoseHeadersMayBeOverridden is ODataBatchOperationResponseMessage) { responseMessageStream.Dispose(); } } }
internal void Write(Stream stream) { IExceptionWriter exceptionWriter = null; Stream output = null; Serializer serializer = null; System.Data.Services.ODataResponseMessage responseMessage = this.responseMessage as System.Data.Services.ODataResponseMessage; if (responseMessage != null) { responseMessage.SetStream(stream); } try { BinarySerializer serializer2; MetadataSerializer serializer7; switch (this.payloadKind) { case ODataPayloadKind.Feed: case ODataPayloadKind.Entry: { EntitySerializer serializer6 = new EntitySerializer(this.requestDescription, this.AbsoluteServiceUri, this.service, this.service.OperationContext.Host.ResponseETag, this.messageWriter, this.contentFormat); serializer = serializer6; serializer6.WriteRequest(this.queryResults, this.hasMoved); return; } case ODataPayloadKind.Property: case ODataPayloadKind.EntityReferenceLink: case ODataPayloadKind.EntityReferenceLinks: case ODataPayloadKind.Collection: { NonEntitySerializer serializer5 = new NonEntitySerializer(this.requestDescription, this.AbsoluteServiceUri, this.service, this.messageWriter); serializer = serializer5; serializer5.WriteRequest(this.queryResults, this.hasMoved); return; } case ODataPayloadKind.Value: new TextSerializer(this.messageWriter).WriteRequest(this.queryResults.Current); return; case ODataPayloadKind.BinaryValue: output = this.responseMessage.GetStream(); serializer2 = new BinarySerializer(output); exceptionWriter = serializer2; if (this.requestDescription.TargetKind != RequestTargetKind.MediaResource) { break; } if (this.mediaResourceStream != null) { serializer2.WriteRequest(this.mediaResourceStream, this.service.StreamProvider.StreamBufferSize); } return; case ODataPayloadKind.ServiceDocument: new ServiceDocumentSerializer(this.messageWriter).WriteServiceDocument(this.service.Provider); return; default: goto Label_0194; } serializer2.WriteRequest(this.queryResults.Current); return; Label_0194: serializer7 = new MetadataSerializer(this.messageWriter); serializer7.WriteMetadataDocument(this.service); } catch (Exception exception) { if (!CommonUtil.IsCatchableExceptionType(exception)) { throw; } if (serializer != null) { serializer.Flush(); } string contentType = this.responseMessage.GetHeader("Content-Type").StartsWith("application/json", StringComparison.OrdinalIgnoreCase) ? "application/json;odata=verbose" : "application/xml"; if (this.messageWriter != null) { ErrorHandler.HandleDuringWritingException(exception, this.service, contentType, this.messageWriter, stream, this.encoding); } else { ErrorHandler.HandleDuringWritingException(exception, this.service, contentType, exceptionWriter); } } finally { WebUtil.Dispose(this.messageWriter); WebUtil.Dispose(this.queryResults); WebUtil.Dispose(this.mediaResourceStream); if ((output != null) && (responseMessage == null)) { output.Dispose(); } } }