Exemple #1
0
        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();
                }
            }
        }