/// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageStream">The message stream to write the payload to.</param>
        /// <param name="encoding">The encoding to use for the payload.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        private ODataMetadataOutputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(synchronous, "Metadata output context is only supported in synchronous operations.");

            try
            {
                this.messageOutputStream = messageStream;
                this.xmlWriter = ODataAtomWriterUtils.CreateXmlWriter(messageStream, messageWriterSettings, encoding);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the output context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageStream">The message stream to write the payload to.</param>
        /// <param name="encoding">The encoding to use for the payload.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        private ODataRawOutputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
        {
            try
            {
                this.messageOutputStream = messageStream;
                this.encoding = encoding;

                if (synchronous)
                {
                    this.outputStream = messageStream;
                }
                else
                {
                    this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
                    this.outputStream = this.asynchronousOutputStream;
                }
            }
            catch
            {
                messageStream.Dispose();
                throw;
            }
        }
        public void ReadJsonLight()
        {
            // Arrange
            var deserializer = new ODataEntityReferenceLinkDeserializer();
            MockODataRequestMessage requestMessage = new MockODataRequestMessage();
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings();
            writerSettings.SetContentType(ODataFormat.Json);
            IEdmModel model = CreateModel();
            ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage, writerSettings, model);
            messageWriter.WriteEntityReferenceLink(new ODataEntityReferenceLink { Url = new Uri("http://localhost/samplelink") });
            ODataMessageReader messageReader = new ODataMessageReader(new MockODataRequestMessage(requestMessage),
                new ODataMessageReaderSettings(), model);

            IEdmNavigationProperty navigationProperty = GetNavigationProperty(model);

            ODataDeserializerContext context = new ODataDeserializerContext
            {
                Request = new HttpRequestMessage(),
                Path = new ODataPath(new NavigationPathSegment(navigationProperty))
            };

            // Act
            Uri uri = deserializer.Read(messageReader, context) as Uri;

            // Assert
            Assert.NotNull(uri);
            Assert.Equal("http://localhost/samplelink", uri.AbsoluteUri);
        }
 private ODataJsonOutputContext(ODataFormat format, Stream messageStream, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver) : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
 {
     try
     {
         Stream asynchronousOutputStream;
         this.messageOutputStream = messageStream;
         if (synchronous)
         {
             asynchronousOutputStream = messageStream;
         }
         else
         {
             this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
             asynchronousOutputStream = this.asynchronousOutputStream;
         }
         this.textWriter = new StreamWriter(asynchronousOutputStream, encoding);
         this.jsonWriter = new Microsoft.Data.OData.Json.JsonWriter(this.textWriter, messageWriterSettings.Indent);
     }
     catch (Exception exception)
     {
         if (ExceptionUtils.IsCatchableExceptionType(exception) && (messageStream != null))
         {
             messageStream.Dispose();
         }
         throw;
     }
 }
 private ODataAtomOutputContext(ODataFormat format, Stream messageStream, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver) : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
 {
     try
     {
         Stream asynchronousOutputStream;
         this.messageOutputStream = messageStream;
         if (synchronous)
         {
             asynchronousOutputStream = messageStream;
         }
         else
         {
             this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
             asynchronousOutputStream = this.asynchronousOutputStream;
         }
         this.xmlRootWriter = ODataAtomWriterUtils.CreateXmlWriter(asynchronousOutputStream, messageWriterSettings, encoding);
         this.xmlWriter = this.xmlRootWriter;
     }
     catch (Exception exception)
     {
         if (ExceptionUtils.IsCatchableExceptionType(exception) && (messageStream != null))
         {
             messageStream.Dispose();
         }
         throw;
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataMediaTypeFormatter"/> class.
        /// </summary>
        /// <param name="deserializerProvider">The <see cref="ODataDeserializerProvider"/> to use.</param>
        /// <param name="serializerProvider">The <see cref="ODataSerializerProvider"/> to use.</param>
        /// <param name="payloadKinds">The kind of payloads this formatter supports.</param>
        public ODataMediaTypeFormatter(ODataDeserializerProvider deserializerProvider, ODataSerializerProvider serializerProvider,
            IEnumerable<ODataPayloadKind> payloadKinds)
        {
            if (deserializerProvider == null)
            {
                throw Error.ArgumentNull("deserializerProvider");
            }
            if (serializerProvider == null)
            {
                throw Error.ArgumentNull("serializerProvider");
            }
            if (payloadKinds == null)
            {
                throw Error.ArgumentNull("payloadKinds");
            }

            _deserializerProvider = deserializerProvider;
            _serializerProvider = serializerProvider;
            _payloadKinds = payloadKinds;

            // Maxing out the received message size as we depend on the hosting layer to enforce this limit.
            MessageWriterSettings = new ODataMessageWriterSettings
            {
                Indent = true,
                DisableMessageStreamDisposal = true,
                MessageQuotas = new ODataMessageQuotas { MaxReceivedMessageSize = Int64.MaxValue }
            };
            MessageReaderSettings = new ODataMessageReaderSettings
            {
                DisableMessageStreamDisposal = true,
                MessageQuotas = new ODataMessageQuotas { MaxReceivedMessageSize = Int64.MaxValue },
            };

            _version = DefaultODataVersion;
        }
        public void ProcessRequest(HttpContext context, Uri serviceBaseUri)
        {
            var sparqlGenerator = new SparqlGenerator(_config.Map, _config.DefaultLanguageCode, _config.MaxPageSize);

            var messageWriterSettings = new ODataMessageWriterSettings(_config.BaseODataWriterSettings)
                {
                    BaseUri = serviceBaseUri
                };
            if (context.Request.AcceptTypes != null)
            {
                messageWriterSettings.SetContentType(String.Join(",", context.Request.AcceptTypes),
                                                     context.Request.Headers["Accept-Charset"]);
            }

            var requestMessage = new HttpDataRequestMessage(context.Request);
            ODataVersion effectiveVersion = GetEffectiveODataVersion(requestMessage);
            messageWriterSettings.Version = effectiveVersion;

            var metadataUri = new Uri(serviceBaseUri, "./$metadata");
            if (serviceBaseUri.Equals(context.Request.Url))
            {
                // We need to respond with the service document
                var responseMessage = new HttpDataResponseMessage(context.Response);
                context.Response.ContentType = "application/xml";
                context.Response.ContentEncoding = System.Text.Encoding.UTF8;
                var feedGenerator = new ODataFeedGenerator(requestMessage, responseMessage,
                                                           _config.Map, serviceBaseUri.ToString(),
                                                           messageWriterSettings);
                feedGenerator.WriteServiceDocument();
            }
            else if (serviceBaseUri.ToString().TrimEnd('/').Equals(context.Request.Url.ToString().TrimEnd('/')))
            {
                // Trimming of trailing slash to normalize - the serviceBaseUri should always have a trailing slash, 
                // but we will redirect requests that do not to the proper service document url
                context.Response.RedirectPermanent(serviceBaseUri.ToString(), true);
            }
            else if (metadataUri.Equals(context.Request.Url))
            {
                context.Response.ContentType = "application/xml";
                context.Response.WriteFile(_config.MetadataPath);
            }
            else
            {
                var parsedQuery = QueryDescriptorQueryNode.ParseUri(
                    context.Request.Url,
                    serviceBaseUri,
                    _config.Model);
                sparqlGenerator.ProcessQuery(parsedQuery);
                var responseMessage = new HttpDataResponseMessage(context.Response);
                var feedGenerator = new ODataFeedGenerator(
                    requestMessage,
                    responseMessage,
                    _config.Map,
                    serviceBaseUri.ToString(),
                    messageWriterSettings);
                sparqlGenerator.SparqlQueryModel.Execute(_config.SparqlEndpoint, feedGenerator);
                context.Response.ContentType = "application/atom+xml";
            }
        }
 /// <summary>
 /// Create a new feed generator
 /// </summary>
 /// <param name="requestMessage">The OData request message that was received</param>
 /// <param name="responseMessage">The OData response message to be populated by the generator</param>
 /// <param name="entityMap">The map to use to map RDF URIs to OData types and properties</param>
 /// <param name="baseUri">The base URI for the OData feed</param>
 /// <param name="messageWriterSettings">Additional settings to apply to the generated OData output</param>
 public ODataFeedGenerator(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage, SparqlMap entityMap, string baseUri, ODataMessageWriterSettings messageWriterSettings)
 {
     _request = requestMessage;
     _response = responseMessage;
     _map = entityMap;
     _baseUri = baseUri;
     _writerSettings = messageWriterSettings;
 }
 private void ConfigureWriterSettings(ODataSparqlServiceConfigurationSection serviceConfiguration)
 {
     BaseODataWriterSettings = new ODataMessageWriterSettings
         {
             Indent = serviceConfiguration.OutputConfiguration.Indent,
             Version = ODataVersion.V3
         };
 }
        /// <summary>
        /// Validates that message writer settings are correct.
        /// </summary>
        /// <param name="messageWriterSettings">The message writer settings to validate.</param>
        internal static void ValidateMessageWriterSettings(ODataMessageWriterSettings messageWriterSettings)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            if (messageWriterSettings.BaseUri != null && !messageWriterSettings.BaseUri.IsAbsoluteUri)
            {
                throw new ODataException(Strings.WriterValidationUtils_MessageWriterSettingsBaseUriMustBeNullOrAbsolute(UriUtilsCommon.UriToString(messageWriterSettings.BaseUri)));
            }
        }
        /// <summary>
        /// Sets the 'DataServiceVersion' HTTP header on the message based on the protocol version specified in the settings.
        /// </summary>
        /// <param name="message">The message to set the data service version header on.</param>
        /// <param name="settings">The <see cref="ODataMessageWriterSettings"/> determining the protocol version to use.</param>
        internal static void SetDataServiceVersion(ODataMessage message, ODataMessageWriterSettings settings)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(message != null, "message != null");
            Debug.Assert(settings != null, "settings != null");
            Debug.Assert(settings.Version.HasValue, "settings.Version.HasValue");

            string dataServiceVersionString = ODataUtils.ODataVersionToString(settings.Version.Value) + ";";
            message.SetHeader(ODataConstants.DataServiceVersionHeader, dataServiceVersionString);
        }
Exemple #12
0
 protected ODataOutputContext(ODataFormat format, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver)
 {
     ExceptionUtils.CheckArgumentNotNull<ODataFormat>(format, "format");
     ExceptionUtils.CheckArgumentNotNull<ODataMessageWriterSettings>(messageWriterSettings, "messageWriterSettings");
     this.format = format;
     this.messageWriterSettings = messageWriterSettings;
     this.writingResponse = writingResponse;
     this.synchronous = synchronous;
     this.model = model;
     this.urlResolver = urlResolver;
 }
        public void ConvertFeed(Uri relativeODataUri, Uri relativeSodaUri, JsonPayload jsonPayload,
		                        DateTimeOffset feedUpdateTime)
        {
            var jsonObject = jsonPayload.JsonObject;

            var entries = jsonObject.PropertyValue<JArray>("entries");
            var meta = jsonObject.PropertyValue<JObject>("meta");
            var view = meta.PropertyValue<JObject>("view");

            IList<string> fieldsToIgnore;
            var model = BuildModel(view, out fieldsToIgnore);

            var entitySet = model.EntityContainers.Single().EntitySets().Single();

            var settings = new ODataMessageWriterSettings
                           	{
                           		Indent = true,
                           	};

            using (var writer = new ODataMessageWriter(Message, settings, model))
            {
                var feedWriter = writer.CreateODataFeedWriter();

                var feed = new ODataFeed();

                feed.SetAnnotation(new AtomFeedMetadata
                                   	{
                                   		Updated = feedUpdateTime,
                                   	});

                feed.Id = new Uri(ODataEndpointUri, relativeODataUri.OriginalString).OriginalString;

                feedWriter.WriteStart(feed);
                foreach (var entry in entries.Cast<JObject>())
                {
                    var entryMetadata = new ODataEntry();
                    entryMetadata.Id = (string) ((JValue) entry.Property("id").Value).Value;
                    entryMetadata.TypeName = entitySet.ElementType.FullName();

                    entryMetadata.Properties = ConvertProperties(entry, fieldsToIgnore);

                    entryMetadata.SetAnnotation(new AtomEntryMetadata
                                                    {
                                                        Updated = ConvertDateTimeOffset(entry.PrimitivePropertyValue<long>("updated_at")),
                                                        Published = ConvertDateTimeOffset(entry.PrimitivePropertyValue<long>("created_at")),
                                                    });

                    feedWriter.WriteStart(entryMetadata);
                    feedWriter.WriteEnd();
                }

                feedWriter.WriteEnd();
            }
        }
 public ODataMessageWriterSettings(ODataMessageWriterSettings settings)
 {
     ExceptionUtils.CheckArgumentNotNull<ODataMessageWriterSettings>(settings, "settings");
     this.acceptCharSets = settings.acceptCharSets;
     this.acceptMediaTypes = settings.acceptMediaTypes;
     this.BaseUri = settings.BaseUri;
     this.CheckCharacters = settings.CheckCharacters;
     this.DisableMessageStreamDisposal = settings.DisableMessageStreamDisposal;
     this.format = settings.format;
     this.Indent = settings.Indent;
     this.messageQuotas = new ODataMessageQuotas(settings.MessageQuotas);
     this.useFormat = settings.useFormat;
     this.Version = settings.Version;
     this.writerBehavior = settings.writerBehavior;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataBatchContent"/> class.
        /// </summary>
        /// <param name="responses">The batch responses.</param>
        /// <param name="writerSettings">The <see cref="ODataMessageWriterSettings"/>.</param>
        public ODataBatchContent(IEnumerable<ODataBatchResponseItem> responses, ODataMessageWriterSettings writerSettings)
        {
            if (responses == null)
            {
                throw Error.ArgumentNull("responses");
            }
            if (writerSettings == null)
            {
                throw Error.ArgumentNull("writerSettings");
            }

            Responses = responses;
            _writerSettings = writerSettings;
            Headers.ContentType = MediaTypeHeaderValue.Parse(String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}", Guid.NewGuid()));
            ODataVersion version = _writerSettings.Version ?? HttpRequestMessageProperties.DefaultODataVersion;
            Headers.TryAddWithoutValidation(HttpRequestMessageProperties.ODataServiceVersionHeader, ODataUtils.ODataVersionToString(version));
        }
        public void ODataMetadataSerializer_Works()
        {
            // Arrange
            ODataMetadataSerializer serializer = new ODataMetadataSerializer();
            MemoryStream stream = new MemoryStream();
            IODataResponseMessage message = new ODataMessageWrapper(stream);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings();
            IEdmModel model = new EdmModel();

            // Act
            serializer.WriteObject("42", typeof(IEdmModel), new ODataMessageWriter(message, settings, model), new ODataSerializerContext());

            // Assert
            stream.Seek(0, SeekOrigin.Begin);
            XElement element = XElement.Load(stream);
            Assert.Equal("Edmx", element.Name.LocalName);
        }
        internal static Tuple<HttpWebRequest, Stream> BuildRequestForTableOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int? timeout, TableOperation operation, OperationContext ctx)
        {
            HttpWebRequest msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, ctx);

            if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge)
            {
                // post tunnelling
                msg.Headers.Add("X-HTTP-Method", "MERGE");
            }

            // etag
            if (operation.OperationType == TableOperationType.Delete ||
                operation.OperationType == TableOperationType.Replace ||
                operation.OperationType == TableOperationType.Merge)
            {
                if (operation.Entity.ETag != null)
                {
                    msg.Headers.Add("If-Match", operation.Entity.ETag);
                }
            }

            if (operation.OperationType == TableOperationType.Insert ||
                operation.OperationType == TableOperationType.Merge ||
                operation.OperationType == TableOperationType.InsertOrMerge ||
                operation.OperationType == TableOperationType.InsertOrReplace ||
                operation.OperationType == TableOperationType.Replace)
            {
                // create the writer, indent for readability of the examples.  
                ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                {
                    CheckCharacters = false,   // sets this flag on the XmlWriter for ATOM  
                    Version = ODataVersion.V2 // set the Odata version to use when writing the entry 
                };

                HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager);
                ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings);
                ODataWriter writer = odataWriter.CreateODataEntryWriter();
                WriteOdataEntity(operation.Entity, operation.OperationType, ctx, writer);

                return new Tuple<HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream());
            }

            return new Tuple<HttpWebRequest, Stream>(msg, null);
        }
        public string UpdateDataToOData(Change[] changes, string tableName, string[] headers)
        {
            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(this.odataEndpointURL, "$batch"));
            requestMessage.Headers.Add("DataServiceVersion", this.odataVersion);
            requestMessage.Headers.Add("MaxDataServiceVersion", this.odataMaxVersion);
            
            var setting = new ODataMessageWriterSettings();
            setting.SetContentType(ODataFormat.Batch);
            setting.BaseUri = this.odataEndpointURL;

            var odataHttpRequest = new ODataHttpRequest(requestMessage);
            var messageWriter = new ODataMessageWriter(odataHttpRequest, setting, this.metadata);

            var batchWriter = messageWriter.CreateODataBatchWriter();
            batchWriter.WriteStartBatch();
            
            for (int i = 0; i < changes.Length; i++)
            {
                batchWriter.WriteStartChangeset();
                if (changes[i].operation == "DELETE")
                {
                    createDeleteOperationRequestMessage(ref batchWriter, changes[i], tableName);
                }

                if (changes[i].operation == "UPDATE")
                {
                    createUpdateOperationRequestMessage(ref batchWriter, changes[i], tableName, headers);
                }
                batchWriter.WriteEndChangeset();
            }
            
            batchWriter.WriteEndBatch();
            batchWriter.Flush();
            odataHttpRequest.GetStream().Seek(0, SeekOrigin.Begin);

            HttpResponseMessage result = new HttpResponseMessage();

            using (HttpClient client = new HttpClient())
            {
                result = client.SendAsync(requestMessage).Result;
            }

            return parseResponseMessage(result);
        }
Exemple #19
0
 private ODataMetadataOutputContext(ODataFormat format, Stream messageStream, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver) : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
 {
     try
     {
         this.messageOutputStream = messageStream;
         this.xmlWriter           = ODataAtomWriterUtils.CreateXmlWriter(messageStream, messageWriterSettings, encoding);
     }
     catch (Exception exception)
     {
         if (ExceptionUtils.IsCatchableExceptionType(exception) && (messageStream != null))
         {
             messageStream.Dispose();
         }
         throw;
     }
 }
        private void WriteToStream(Type type, object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)
        {
            IEdmModel model = Request.GetEdmModel();
            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
            }

            ODataSerializer serializer = GetSerializer(type, value, model, _serializerProvider);

            UrlHelper urlHelper = Request.GetUrlHelper();
            Contract.Assert(urlHelper != null);

            ODataPath path = Request.GetODataPath();
            IEdmEntitySet targetEntitySet = path == null ? null : path.EntitySet;

            // serialize a response
            HttpConfiguration configuration = Request.GetConfiguration();
            if (configuration == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration);
            }

            IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream, content.Headers);

            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings(MessageWriterSettings)
            {
                BaseUri = GetBaseAddress(Request),
                Version = _version,
            };

            // The MetadataDocumentUri is never required for errors. Additionally, it sometimes won't be available
            // for errors, such as when routing itself fails. In that case, the route data property is not
            // available on the request, and due to a bug with HttpRoute.GetVirtualPath (bug #669) we won't be able
            // to generate a metadata link.
            if (serializer.ODataPayloadKind != ODataPayloadKind.Error)
            {
                string metadataLink = urlHelper.ODataLink(new MetadataPathSegment());

                if (metadataLink == null)
                {
                    throw new SerializationException(SRResources.UnableToDetermineMetadataUrl);
                }

                string selectClause = GetSelectClause(Request);
                writerSettings.SetMetadataDocumentUri(new Uri(metadataLink), selectClause);
            }

            MediaTypeHeaderValue contentType = null;
            if (contentHeaders != null && contentHeaders.ContentType != null)
            {
                contentType = contentHeaders.ContentType;
            }

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
            {
                ODataSerializerContext writeContext = new ODataSerializerContext()
                {
                    Request = Request,
                    RequestContext = Request.GetRequestContext(),
                    Url = urlHelper,
                    EntitySet = targetEntitySet,
                    Model = model,
                    RootElementName = GetRootElementName(path) ?? "root",
                    SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed,
                    Path = path,
                    MetadataLevel = ODataMediaTypes.GetMetadataLevel(contentType),
                    SelectExpandClause = Request.GetSelectExpandClause()
                };

                serializer.WriteObject(value, type, messageWriter, writeContext);
            }
        }
 private ODataRawOutputContext(ODataFormat format, Stream messageStream, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver) : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
 {
     try
     {
         this.messageOutputStream = messageStream;
         this.encoding            = encoding;
         if (synchronous)
         {
             this.outputStream = messageStream;
         }
         else
         {
             this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
             this.outputStream             = this.asynchronousOutputStream;
         }
     }
     catch
     {
         messageStream.Dispose();
         throw;
     }
 }
 private static ODataMessageWriterSettings CreateJsonLightSettings()
 {
     ODataMessageWriterSettings settings = new ODataMessageWriterSettings();
     settings.SetContentType(ODataFormat.Json);
     settings.SetMetadataDocumentUri(CreateFakeUri());
     return settings;
 }
Exemple #23
0
 private static ODataMessageWriterSettings CreateMessageWriterSettings(Uri serviceUri, DataServiceProviderWrapper provider, Version responseVersion, bool disableDisposeStream, ODataFormat format)
 {
     ODataMessageWriterSettings settings = new ODataMessageWriterSettings {
         BaseUri = serviceUri,
         Version = new ODataVersion?(CommonUtil.ConvertToODataVersion(responseVersion)),
         Indent = false,
         CheckCharacters = false,
         DisableMessageStreamDisposal = disableDisposeStream
     };
     settings.EnableWcfDataServicesServerBehavior(provider.IsV1Provider);
     settings.SetContentType(format);
     return settings;
 }
        /// <summary>
        /// Copy constructor to create a copy of the settings for OData writers.
        /// </summary>
        /// <param name="settings">Settings to create a copy from</param>
        public ODataMessageWriterSettings(ODataMessageWriterSettings settings)
        {
            ExceptionUtils.CheckArgumentNotNull(settings, "settings");

            this.acceptCharSets = settings.acceptCharSets;
            this.acceptMediaTypes = settings.acceptMediaTypes;
            this.BaseUri = settings.BaseUri;
            this.CheckCharacters = settings.CheckCharacters;
            this.DisableMessageStreamDisposal = settings.DisableMessageStreamDisposal;
            this.format = settings.format;
            this.Indent = settings.Indent;
            this.messageQuotas = new ODataMessageQuotas(settings.MessageQuotas);
            this.useFormat = settings.useFormat;
            this.Version = settings.Version;
            this.atomFormatStartEntryXmlCustomizationCallback = settings.atomFormatStartEntryXmlCustomizationCallback;
            this.atomFormatEndEntryXmlCustomizationCallback = settings.atomFormatEndEntryXmlCustomizationCallback;

            // NOTE: writer behavior is immutable; copy by reference is ok.
            this.writerBehavior = settings.writerBehavior;
        }
Exemple #25
0
 internal static ODataOutputContext CreateOutputContext(ODataFormat format, ODataMessage message, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, IEdmModel model, IODataUrlResolver urlResolver)
 {
     if (format == ODataFormat.Atom)
     {
         return(ODataAtomOutputContext.Create(format, message, encoding, messageWriterSettings, writingResponse, model, urlResolver));
     }
     if (format == ODataFormat.VerboseJson)
     {
         return(ODataJsonOutputContext.Create(format, message, encoding, messageWriterSettings, writingResponse, model, urlResolver));
     }
     if (format == ODataFormat.Metadata)
     {
         return(ODataMetadataOutputContext.Create(format, message, encoding, messageWriterSettings, writingResponse, model, urlResolver));
     }
     if ((format != ODataFormat.Batch) && (format != ODataFormat.RawValue))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.ODataOutputContext_CreateOutputContext_UnrecognizedFormat));
     }
     return(ODataRawOutputContext.Create(format, message, encoding, messageWriterSettings, writingResponse, model, urlResolver));
 }
 internal static ODataOutputContext Create(ODataFormat format, ODataMessage message, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, IEdmModel model, IODataUrlResolver urlResolver)
 {
     return(new ODataRawOutputContext(format, message.GetStream(), encoding, messageWriterSettings, writingResponse, true, model, urlResolver));
 }
        private IEnumerable<KeyValuePair<string, string>> GetResponseMessageHeaders(Type graphType, ODataFormat odataFormat, ODataVersion version)
        {
            IODataResponseMessage responseMessage = new ODataMessageWrapper();

            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
            {
                BaseUri = new Uri(ODataFormatterConstants.DefaultNamespace),
                Version = version,
                Indent = false
            };
            writerSettings.SetContentType(odataFormat);
            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings))
            {
                ODataSerializer serializer = ODataSerializerProvider.GetODataPayloadSerializer(graphType);

                // get the OData specific headers for the payloadkind
                ODataUtils.SetHeadersForPayload(messageWriter, serializer.ODataPayloadKind);
            }

            return responseMessage.Headers;
        }
 internal static Task <ODataOutputContext> CreateAsync(ODataFormat format, ODataMessage message, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, IEdmModel model, IODataUrlResolver urlResolver)
 {
     return(message.GetStreamAsync().FollowOnSuccessWith <Stream, ODataOutputContext>(streamTask => new ODataRawOutputContext(format, streamTask.Result, encoding, messageWriterSettings, writingResponse, false, model, urlResolver)));
 }
        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (writeStream == null)
            {
                throw Error.ArgumentNull("writeStream");
            }

            if (Request == null)
            {
                throw Error.NotSupported(SRResources.WriteToStreamAsyncMustHaveRequest);
            }

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;
            return TaskHelpers.RunSynchronously(() =>
            {
                // Get the format and version to use from the ODataServiceVersion content header or if not available use the
                // values configured for the specialized formatter instance.
                ODataVersion version;
                ODataFormat odataFormat;
                if (contentHeaders == null)
                {
                    version = _defaultODataVersion;
                    odataFormat = ODataFormatterConstants.DefaultODataFormat;
                }
                else
                {
                    version = GetODataVersion(contentHeaders, ODataFormatterConstants.ODataServiceVersion) ?? _defaultODataVersion;
                    odataFormat = GetODataFormat(contentHeaders);
                }

                ODataSerializer serializer = ODataSerializerProvider.GetODataPayloadSerializer(type);
                if (serializer == null)
                {
                    throw Error.InvalidOperation(SRResources.TypeCannotBeSerialized, type.Name, typeof(ODataMediaTypeFormatter).Name);
                }

                UrlHelper urlHelper = Request.GetUrlHelper();
                NameValueCollection queryStringValues = Request.RequestUri.ParseQueryString();

                IEdmEntitySet targetEntitySet = null;
                ODataUriHelpers.TryGetEntitySetAndEntityType(Request.RequestUri, Model, out targetEntitySet);

                ODataQueryProjectionNode rootProjectionNode = null;
                if (targetEntitySet != null)
                {
                    // TODO: Bug 467621: Move to ODataUriParser once it is done.
                    rootProjectionNode = ODataUriHelpers.GetODataQueryProjectionNode(queryStringValues["$select"], queryStringValues["$expand"], targetEntitySet);
                }

                // serialize a response
                Uri baseAddress = new Uri(Request.RequestUri, Request.GetConfiguration().VirtualPathRoot);

                // TODO: Bug 467617: figure out the story for the operation name on the client side and server side.
                // This is clearly a workaround. We are assuming that the operation name is the last segment in the request uri 
                // which works for most cases and fall back to the type name of the object being written.
                // We should rather use uri parser semantic tree to figure out the operation name from the request url.
                string operationName = ODataUriHelpers.GetOperationName(Request.RequestUri, baseAddress);
                operationName = operationName ?? type.Name;

                IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream);

                ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                {
                    BaseUri = baseAddress,
                    Version = version,
                    Indent = true,
                    DisableMessageStreamDisposal = true,
                };
                if (contentHeaders != null && contentHeaders.ContentType != null)
                {
                    writerSettings.SetContentType(contentHeaders.ContentType.ToString(), Encoding.UTF8.WebName);
                }

                using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, ODataDeserializerProvider.EdmModel))
                {
                    ODataSerializerContext writeContext = new ODataSerializerContext()
                                                                    {
                                                                        EntitySet = targetEntitySet,
                                                                        UrlHelper = urlHelper,
                                                                        RootProjectionNode = rootProjectionNode,
                                                                        CurrentProjectionNode = rootProjectionNode,
                                                                        ServiceOperationName = operationName
                                                                    };

                    serializer.WriteObject(value, messageWriter, writeContext);
                }
            });
        }
Exemple #30
0
        /// <summary>
        /// Given the Accept and the Accept-Charset headers of the request message computes the media type, encoding and <see cref="ODataFormat"/>
        /// to be used for the response message.
        /// </summary>
        /// <param name="settings">The message writer settings to use for serializing the response payload.</param>
        /// <param name="payloadKind">The kind of payload to be serialized as part of the response message.</param>
        /// <param name="mediaTypeResolver">The media type resolver to use when interpreting the content type.</param>
        /// <param name="mediaType">The media type to be used in the response message.</param>
        /// <param name="encoding">The encoding to be used in the response message.</param>
        /// <returns>The <see cref="ODataFormat"/> used when serializing the response.</returns>
        internal static ODataFormat GetContentTypeFromSettings(
            ODataMessageWriterSettings settings,
            ODataPayloadKind payloadKind,
            MediaTypeResolver mediaTypeResolver,
            out MediaType mediaType,
            out Encoding encoding)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(settings != null, "settings != null");

            // compute format, media type and encoding
            ODataFormat format;

            // get the supported and default media types for the specified payload kind
            IList <MediaTypeWithFormat> supportedMediaTypes = mediaTypeResolver.GetMediaTypesForPayloadKind(payloadKind);

            if (supportedMediaTypes == null || supportedMediaTypes.Count == 0)
            {
                throw new ODataContentTypeException(Strings.MediaTypeUtils_DidNotFindMatchingMediaType(null, settings.AcceptableMediaTypes));
            }

            if (settings.UseFormat == true)
            {
                Debug.Assert(settings.AcceptableMediaTypes == null, "settings.AcceptableMediaTypes == null");
                Debug.Assert(settings.AcceptableCharsets == null, "settings.AcceptableCharsets == null");

                mediaType = GetDefaultMediaType(supportedMediaTypes, settings.Format, out format);

                // NOTE the default media types don't have any parameters (in particular no 'charset' parameters)
                encoding = mediaType.SelectEncoding();
            }
            else
            {
                // parse the accept header into its parts
                IList <KeyValuePair <MediaType, string> > specifiedTypes = HttpUtils.MediaTypesFromString(settings.AcceptableMediaTypes);

                // Starting in V3 we replace all occurrences of application/json with application/json;odata=minimalmetadata
                // before handing the acceptable media types to the conneg code. This is necessary because for an accept
                // header 'application/json, application/json;odata=verbose' we want to the result to be 'application/json;odata=minimalmetadata'
                // although this is not compliant with the default conneg rules (where application/json;odata=verbose would win).
                if (settings.Version >= ODataVersion.V3)
                {
                    ConvertApplicationJsonInAcceptableMediaTypes(specifiedTypes);
                }

                MediaTypeWithFormat selectedMediaTypeWithFormat;
                string specifiedCharset = null;
                if (specifiedTypes == null || specifiedTypes.Count == 0)
                {
                    selectedMediaTypeWithFormat = supportedMediaTypes[0];
                }
                else
                {
                    // match the specified media types against the supported/default ones and get the format
                    MediaTypeMatchInfo matchInfo = MatchMediaTypes(specifiedTypes.Select(kvp => kvp.Key), supportedMediaTypes.Select(smt => smt.MediaType).ToArray());
                    if (matchInfo == null)
                    {
                        // We're calling the ToArray here since not all platforms support the string.Join which takes IEnumerable.
                        string supportedTypesAsString = String.Join(", ", supportedMediaTypes.Select(mt => mt.MediaType.ToText()).ToArray());
                        throw new ODataContentTypeException(Strings.MediaTypeUtils_DidNotFindMatchingMediaType(supportedTypesAsString, settings.AcceptableMediaTypes));
                    }

                    selectedMediaTypeWithFormat = supportedMediaTypes[matchInfo.TargetTypeIndex];
                    specifiedCharset            = specifiedTypes[matchInfo.SourceTypeIndex].Value;
                }

                format    = selectedMediaTypeWithFormat.Format;
                mediaType = selectedMediaTypeWithFormat.MediaType;

                // If a charset was specified with the accept header, consider it for the encoding
                string acceptableCharsets = settings.AcceptableCharsets;
                if (specifiedCharset != null)
                {
                    acceptableCharsets = acceptableCharsets == null ? specifiedCharset : specifiedCharset + "," + acceptableCharsets;
                }

                encoding = GetEncoding(acceptableCharsets, payloadKind, mediaType, /*useDefaultEncoding*/ true);
            }

            return(format);
        }
        public void ConvertMetadata(Uri relativeODataUri, Uri relativeSodaUri, JsonPayload jsonPayload)
        {
            var jsonObject = jsonPayload.JsonObject;

            var meta = jsonObject.PropertyValue<JObject>("meta");
            var view = meta.PropertyValue<JObject>("view");

            IList<string> fieldsToIgnore;
            var model = BuildModel(view, out fieldsToIgnore);

            var settings = new ODataMessageWriterSettings
                           	{
                           		Indent = true,
                           	};

            using (var writer = new ODataMessageWriter(Message, settings, model))
            {
                writer.WriteMetadataDocument();
            }
        }
        internal static Tuple<HttpWebRequest, Stream> BuildRequestForTableBatchOperation(Uri uri, UriQueryBuilder builder, int? timeout, Uri baseUri, string tableName, TableBatchOperation batch, OperationContext ctx)
        {
            HttpWebRequest msg = BuildRequestCore(NavigationHelper.AppendPathToUri(uri, "$batch"), builder, "POST", timeout, ctx);

            // create the writer, indent for readability of the examples.  
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
            {
                CheckCharacters = false,   // sets this flag on the XmlWriter for ATOM  
                Version = ODataVersion.V2 // set the Odata version to use when writing the entry 
            };

            HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg);

            // Start Batch
            ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings);
            ODataBatchWriter batchWriter = odataWriter.CreateODataBatchWriter();
            batchWriter.WriteStartBatch();

            bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve;

            // Query operations should not be inside changeset in payload
            if (!isQuery)
            {
                // Start Operation
                batchWriter.WriteStartChangeset();
                batchWriter.Flush();
            }

            foreach (TableOperation operation in batch)
            {
                string httpMethod = operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge ? "MERGE" : operation.HttpMethod;

                ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(baseUri, tableName));

                // etag
                if (operation.OperationType == TableOperationType.Delete ||
                    operation.OperationType == TableOperationType.Replace ||
                    operation.OperationType == TableOperationType.Merge)
                {
                    mimePartMsg.SetHeader("If-Match", operation.Entity.ETag);
                }

                if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve)
                {
                    using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings))
                    {
                        // Write entity
                        ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter();
                        WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter);
                    }
                }
            }

            if (!isQuery)
            {
                // End Operation
                batchWriter.WriteEndChangeset();
            }

            // End Batch
            batchWriter.WriteEndBatch();
            batchWriter.Flush();

            return new Tuple<HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream());
        }
        public void ODataEntityReferenceLinkSerializer_Serializes_UrisAndEntityReferenceLinks_Json(object uris)
        {
            // Arrange
            ODataEntityReferenceLinksSerializer serializer = new ODataEntityReferenceLinksSerializer();
            IEdmNavigationProperty navigationProperty = _customerSet.ElementType.NavigationProperties().First();
            ODataPath path = new ODataPath(new EntitySetPathSegment(_customerSet), new KeyValuePathSegment("1"),
                new NavigationPathSegment(navigationProperty));
            ODataSerializerContext writeContext = new ODataSerializerContext { Path = path };
            MemoryStream stream = new MemoryStream();
            IODataResponseMessage message = new ODataMessageWrapper(stream);

            ODataMessageWriterSettings settings = new ODataMessageWriterSettings
            {
                BaseUri = new Uri("http://any/")
            };
            settings.SetMetadataDocumentUri(new Uri("http://any/$metadata"));
            settings.SetContentType(ODataFormat.Json);

            // Act
            serializer.WriteObject(uris, typeof(ODataEntityReferenceLinks), new ODataMessageWriter(message, settings), writeContext);
            stream.Seek(0, SeekOrigin.Begin);
            string result = new StreamReader(stream).ReadToEnd();

            // Assert
            Assert.Equal(
                string.Format("{0},{1}",
                    "{\"odata.metadata\":\"http://any/$metadata#Default.Container.Customers/$links/Orders\"",
                    "\"value\":[{\"url\":\"http://uri1/\"},{\"url\":\"http://uri2/\"}]}"), result);
        }
        internal static Tuple<HttpWebRequest, Stream> BuildRequestForTableBatchOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int? timeout, string tableName, TableBatchOperation batch, bool useVersionHeader, OperationContext ctx, TableRequestOptions options, string accountName)
        {
            HttpWebRequest msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, "POST", timeout, useVersionHeader, ctx);
            TablePayloadFormat payloadFormat = options.PayloadFormat.Value;
            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);

            // create the writer, indent for readability of the examples.  
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
            {
                CheckCharacters = false,   // sets this flag on the XmlWriter for ATOM  
                Version = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry 
            };

            HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager);

            ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings);

            ODataBatchWriter batchWriter = odataWriter.CreateODataBatchWriter();
            batchWriter.WriteStartBatch();

            bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve;

            // Query operations should not be inside changeset in payload
            if (!isQuery)
            {
                // Start Operation
                batchWriter.WriteStartChangeset();
                batchWriter.Flush();
            }

            foreach (TableOperation operation in batch)
            {
                string httpMethod = operation.HttpMethod;
                if (operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge)
                {
                    options.AssertNoEncryptionPolicyOrStrictMode();
                    httpMethod = "MERGE";
                }

                ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(uri, tableName));
                SetAcceptAndContentTypeForODataBatchMessage(mimePartMsg, payloadFormat);

                // etag
                if (operation.OperationType == TableOperationType.Delete ||
                    operation.OperationType == TableOperationType.Replace ||
                    operation.OperationType == TableOperationType.Merge)
                {
                    mimePartMsg.SetHeader("If-Match", operation.Entity.ETag);
                }

                // Prefer header
                if (operation.OperationType == TableOperationType.Insert)
                {
                    mimePartMsg.SetHeader("Prefer", operation.EchoContent ? "return-content" : "return-no-content");
                }
                
                if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve)
                {
                    using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings, new TableStorageModel(accountName)))
                    {
                        // Write entity
                        ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter();
                        WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter, options);
                    }
                }
            }

            if (!isQuery)
            {
                // End Operation
                batchWriter.WriteEndChangeset();
            }

            // End Batch
            batchWriter.WriteEndBatch();
            batchWriter.Flush();

            return new Tuple<HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream());
        }
        internal static Tuple<HttpWebRequest, Stream> BuildRequestForTableOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int? timeout, TableOperation operation, bool useVersionHeader, OperationContext ctx, TableRequestOptions options, string accountName)
        {
            HttpWebRequest msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, useVersionHeader, ctx);

            TablePayloadFormat payloadFormat = options.PayloadFormat.Value;

            // Set Accept and Content-Type based on the payload format.
            SetAcceptHeaderForHttpWebRequest(msg, payloadFormat);
            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);

            if (operation.HttpMethod != "HEAD" && operation.HttpMethod != "GET")
            {
                SetContentTypeForHttpWebRequest(msg, payloadFormat);
            }

            if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge)
            {
                options.AssertNoEncryptionPolicyOrStrictMode();

                // post tunnelling
                msg.Headers.Add("X-HTTP-Method", "MERGE");
            }

            // etag
            if (operation.OperationType == TableOperationType.Delete ||
                operation.OperationType == TableOperationType.Replace ||
                operation.OperationType == TableOperationType.Merge)
            {
                if (operation.Entity.ETag != null)
                {
                    msg.Headers.Add("If-Match", operation.Entity.ETag);
                }
            }

            // prefer header
            if (operation.OperationType == TableOperationType.Insert)
            {
                msg.Headers.Add("Prefer", operation.EchoContent ? "return-content" : "return-no-content");
            }
            
            if (operation.OperationType == TableOperationType.Insert ||
                operation.OperationType == TableOperationType.Merge ||
                operation.OperationType == TableOperationType.InsertOrMerge ||
                operation.OperationType == TableOperationType.InsertOrReplace ||
                operation.OperationType == TableOperationType.Replace)
            {
                // create the writer, indent for readability of the examples.  
                ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                {
                    CheckCharacters = false,   // sets this flag on the XmlWriter for ATOM  
                    Version = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry 
                };

                HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager);

                if (operation.HttpMethod != "HEAD" && operation.HttpMethod != "GET")
                {
                    SetContentTypeForAdapterMessage(adapterMsg, payloadFormat);
                }
                
                ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings, new TableStorageModel(accountName));
                ODataWriter writer = odataWriter.CreateODataEntryWriter();
                WriteOdataEntity(operation.Entity, operation.OperationType, ctx, writer, options);

                return new Tuple<HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream());
            }

            return new Tuple<HttpWebRequest, Stream>(msg, null);
        }
        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (writeStream == null)
            {
                throw Error.ArgumentNull("writeStream");
            }

            if (_request == null)
            {
                throw Error.InvalidOperation(SRResources.WriteToStreamAsyncMustHaveRequest);
            }

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;
            return TaskHelpers.RunSynchronously(() =>
            {
                // get the most appropriate serializer given that we support inheritance.
                IEdmModel model = _request.GetEdmModel();
                if (model == null)
                {
                    throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
                }

                type = value == null ? type : value.GetType();
                ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(model, type);
                if (serializer == null)
                {
                    string message = Error.Format(SRResources.TypeCannotBeSerialized, type.Name, typeof(ODataMediaTypeFormatter).Name);
                    throw new SerializationException(message);
                }

                UrlHelper urlHelper = _request.GetUrlHelper();
                Contract.Assert(urlHelper != null);

                ODataPath path = _request.GetODataPath();
                IEdmEntitySet targetEntitySet = path == null ? null : path.EntitySet;

                // serialize a response
                HttpConfiguration configuration = _request.GetConfiguration();
                if (configuration == null)
                {
                    throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration);
                }

                IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream, content.Headers);

                ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                {
                    BaseUri = GetBaseAddress(_request),
                    Version = _version,
                    Indent = true,
                    DisableMessageStreamDisposal = true,
                    MessageQuotas = MessageWriterQuotas
                };

                // The MetadataDocumentUri is never required for errors. Additionally, it sometimes won't be available
                // for errors, such as when routing itself fails. In that case, the route data property is not
                // available on the request, and due to a bug with HttpRoute.GetVirtualPath (bug #669) we won't be able
                // to generate a metadata link.
                if (serializer.ODataPayloadKind != ODataPayloadKind.Error)
                {
                    string metadataLink = urlHelper.ODataLink(new MetadataPathSegment());

                    if (metadataLink == null)
                    {
                        throw new SerializationException(SRResources.UnableToDetermineMetadataUrl);
                    }

                    writerSettings.SetMetadataDocumentUri(new Uri(metadataLink));
                }

                MediaTypeHeaderValue contentType = null;
                if (contentHeaders != null && contentHeaders.ContentType != null)
                {
                    contentType = contentHeaders.ContentType;
                }

                using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
                {
                    ODataSerializerContext writeContext = new ODataSerializerContext()
                    {
                        Request = _request,
                        Url = urlHelper,
                        EntitySet = targetEntitySet,
                        Model = model,
                        RootElementName = GetRootElementName(path) ?? "root",
                        SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed,
                        Path = path,
                        MetadataLevel = ODataMediaTypes.GetMetadataLevel(contentType),
                    };

                    serializer.WriteObject(value, messageWriter, writeContext);
                }
            });
        }
        /// <summary>
        /// Creates an instance of the output context for the specified format.
        /// </summary>
        /// <param name="format">The format to create the context for.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        /// <returns>The newly created output context.</returns>
        internal static ODataOutputContext CreateOutputContext(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();

            if (format == ODataFormat.Atom)
            {
                return(ODataAtomOutputContext.Create(
                           format,
                           message,
                           encoding,
                           messageWriterSettings,
                           writingResponse,
                           model,
                           urlResolver));
            }

            if (format == ODataFormat.VerboseJson)
            {
                return(ODataJsonOutputContext.Create(
                           format,
                           message,
                           encoding,
                           messageWriterSettings,
                           writingResponse,
                           model,
                           urlResolver));
            }

            if (format == ODataFormat.Metadata)
            {
                return(ODataMetadataOutputContext.Create(
                           format,
                           message,
                           encoding,
                           messageWriterSettings,
                           writingResponse,
                           model,
                           urlResolver));
            }

            if (format == ODataFormat.Batch || format == ODataFormat.RawValue)
            {
                return(ODataRawOutputContext.Create(
                           format,
                           message,
                           encoding,
                           messageWriterSettings,
                           writingResponse,
                           model,
                           urlResolver));
            }

            throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataOutputContext_CreateOutputContext_UnrecognizedFormat));
        }