/// <summary> /// Constructor. /// </summary> /// <param name="stream">The stream to write to.</param> /// <param name="odataWriterSettings">Configuration settings for the writer to create.</param> /// <param name="encoding">The encoding to use for writing.</param> /// <param name="writingResponse">True if the writer is to write a response payload; false if it's to write a request payload.</param> /// <param name="metadataProvider">The metadata provider to use.</param> /// <param name="writingFeed">True if the writer is created for writing a feed; false when it is created for writing an entry.</param> /// <param name="synchronous">True if the writer is created for synchronous operation; false for asynchronous.</param> internal ODataJsonWriter( Stream stream, ODataWriterSettings odataWriterSettings, Encoding encoding, bool writingResponse, DataServiceMetadataProviderWrapper metadataProvider, bool writingFeed, bool synchronous) : base( odataWriterSettings.Version, odataWriterSettings.BaseUri, writingResponse, metadataProvider, writingFeed, synchronous) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(stream != null, "stream != null"); Debug.Assert(odataWriterSettings != null, "odataWriterSettings != null"); this.outputStream = new AsyncBufferedStream(stream); this.textWriter = new StreamWriter(this.outputStream, encoding); this.jsonWriter = new JsonWriter(this.textWriter, odataWriterSettings.Indent); }
/// <summary> /// Writes property names and value pairs. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="owningType">The <see cref="ResourceType"/> of the entry (or null if not metadata is available).</param> /// <param name="properties">The enumeration of properties to write out.</param> /// <param name="version">The protocol version used for writing.</param> internal static void WriteProperties( JsonWriter jsonWriter, DataServiceMetadataProviderWrapper metadata, ResourceType owningType, IEnumerable<ODataProperty> properties, ODataVersion version) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); if (properties == null) { return; } foreach (ODataProperty property in properties) { WriteProperty(jsonWriter, metadata, property, owningType, version); } }
/// <summary> /// Writes a set of links (Uris) in response to a $links query; includes optional count and next-page-link information. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="baseUri">The base Uri used for writing.</param> /// <param name="associatedEntityLinks">The set of associated entity links to write out.</param> /// <param name="includeResultsWrapper">True if the 'results' wrapper should be included into the payload; otherwise false.</param> private static void WriteAssociatedEntityLinks(JsonWriter jsonWriter, Uri baseUri, ODataAssociatedEntityLinks associatedEntityLinks, bool includeResultsWrapper) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(associatedEntityLinks != null, "links != null"); if (includeResultsWrapper) { // { jsonWriter.StartObjectScope(); } if (associatedEntityLinks.InlineCount.HasValue) { Debug.Assert(includeResultsWrapper, "Expected 'includeResultsWrapper' to be true if a count is specified."); jsonWriter.WriteName(JsonConstants.ODataCountName); jsonWriter.WriteValue(associatedEntityLinks.InlineCount.Value); } if (includeResultsWrapper) { // "results": jsonWriter.WriteDataArrayName(); } jsonWriter.StartArrayScope(); IEnumerable<ODataAssociatedEntityLink> entityLinks = associatedEntityLinks.Links; if (entityLinks != null) { foreach (ODataAssociatedEntityLink link in entityLinks) { WriteAssociatedEntityLink(jsonWriter, baseUri, link); } } jsonWriter.EndArrayScope(); if (associatedEntityLinks.NextLink != null) { // "__next": ... Debug.Assert(includeResultsWrapper, "Expected 'includeResultsWrapper' to be true if a next page link is specified."); jsonWriter.WriteName(JsonConstants.ODataNextLinkName); jsonWriter.WriteValue(UriUtils.UriToString(associatedEntityLinks.NextLink)); } if (includeResultsWrapper) { jsonWriter.EndObjectScope(); } }
/// <summary> /// Writes a single Uri in response to a $links query. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="baseUri">The base Uri used for writing.</param> /// <param name="link">The associated entity link to write out.</param> private static void WriteAssociatedEntityLink(JsonWriter jsonWriter, Uri baseUri, ODataAssociatedEntityLink link) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(link != null, "link != null"); jsonWriter.StartObjectScope(); jsonWriter.WriteName(JsonConstants.ODataUriName); jsonWriter.WriteValue(UriToAbsoluteUriString(link.Url, baseUri)); jsonWriter.EndObjectScope(); }
/// <summary> /// Writes a name/value pair for a property. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="property">The property to write out.</param> /// <param name="owningType">The type owning the property (or null if no metadata is available).</param> /// <param name="version">The protocol version used for writing.</param> private static void WriteProperty( JsonWriter jsonWriter, DataServiceMetadataProviderWrapper metadata, ODataProperty property, ResourceType owningType, ODataVersion version) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); ValidationUtils.ValidateProperty(property); ResourceProperty resourceProperty = ValidationUtils.ValidatePropertyDefined(property.Name, owningType); bool isOpenPropertyType = owningType != null && owningType.IsOpenType && resourceProperty == null; jsonWriter.WriteName(property.Name); object value = property.Value; if (value == null) { // verify that MultiValue properties are not null if (resourceProperty != null && resourceProperty.Kind == ResourcePropertyKind.MultiValue) { throw new ODataException(Strings.ODataWriter_MultiValuePropertiesMustNotHaveNullValue(resourceProperty.Name)); } jsonWriter.WriteValue(null); } else { ResourceType resourcePropertyType = resourceProperty == null ? null : resourceProperty.ResourceType; ODataComplexValue complexValue = value as ODataComplexValue; if (complexValue != null) { WriteComplexValue(jsonWriter, metadata, complexValue, resourcePropertyType, isOpenPropertyType, version); } else { ODataMultiValue multiValue = value as ODataMultiValue; if (multiValue != null) { ODataVersionChecker.CheckMultiValueProperties(version, property.Name); WriteMultiValue(jsonWriter, metadata, multiValue, resourcePropertyType, isOpenPropertyType, version); } else { WritePrimitiveValue(jsonWriter, value, resourcePropertyType); } } } }
/// <summary> /// Writes out the value of a MultiValue property. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="multiValue">The bag value to write.</param> /// <param name="metadataType">The metadata type for the MultiValue.</param> /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param> /// <param name="version">The protocol version used for writing.</param> private static void WriteMultiValue( JsonWriter jsonWriter, DataServiceMetadataProviderWrapper metadata, ODataMultiValue multiValue, ResourceType metadataType, bool isOpenPropertyType, ODataVersion version) { Debug.Assert(multiValue != null, "multiValue != null"); // Start the object scope which will represent the entire MultiValue instance jsonWriter.StartObjectScope(); // "__metadata": { "type": "typename" } // If the MultiValue has type information write out the metadata and the type in it. string typeName = multiValue.TypeName; // resolve the type name to the resource type; if no type name is specified we will use the // type inferred from metadata ResourceType multiValueType = MetadataUtils.ResolveTypeName(metadata, metadataType, ref typeName, ResourceTypeKind.MultiValue, isOpenPropertyType); if (typeName != null) { // Write the __metadata object jsonWriter.WriteName(JsonConstants.ODataMetadataName); jsonWriter.StartObjectScope(); // "type": "typename" jsonWriter.WriteName(JsonConstants.ODataMetadataTypeName); jsonWriter.WriteValue(typeName); // End the __metadata jsonWriter.EndObjectScope(); } // "results": [ // This represents the array of items in the MultiValue jsonWriter.WriteDataArrayName(); jsonWriter.StartArrayScope(); // Iterate through the MultiValue items and write them out (treat null Items as an empty enumeration) IEnumerable items = multiValue.Items; if (items != null) { ResourceType expectedItemType = multiValueType == null ? null : ((MultiValueResourceType)multiValueType).ItemType; foreach (object item in items) { ValidationUtils.ValidateMultiValueItem(item); ODataComplexValue itemAsComplexValue = item as ODataComplexValue; if (itemAsComplexValue != null) { WriteComplexValue(jsonWriter, metadata, itemAsComplexValue, expectedItemType, false, version); } else { ODataMultiValue itemAsMultiValue = item as ODataMultiValue; if (itemAsMultiValue != null) { throw new ODataException(Strings.ODataWriter_NestedMultiValuesAreNotSupported); } else { WritePrimitiveValue(jsonWriter, item, expectedItemType); } } } } // End the array scope which holds the items jsonWriter.EndArrayScope(); // End the object scope which holds the entire MultiValue jsonWriter.EndObjectScope(); }
/// <summary> /// Dispose the writer and the underlying stream. /// </summary> public void Dispose() { try { if (this.atomWriter == null) { if (this.textWriter == null) { this.asyncBufferedStream.Dispose(); } else { // The text writer will also dispose the this.asyncBufferedStream since it owns that stream // which in turn will dispose the real output stream underneath it. this.textWriter.Dispose(); } } else { Utils.TryDispose(this.atomWriter); this.asyncBufferedStream.Dispose(); } } finally { this.asyncBufferedStream = null; this.jsonWriter = null; this.atomWriter = null; } }
/// <summary> /// Writes out the value of a complex property. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="complexValue">The complex value to write.</param> /// <param name="resourcePropertyType">The metadata type for the complex value.</param> /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param> /// <param name="version">The protocol version used for writing.</param> internal static void WriteComplexValue( JsonWriter jsonWriter, DataServiceMetadataProviderWrapper metadata, ODataComplexValue complexValue, ResourceType resourcePropertyType, bool isOpenPropertyType, ODataVersion version) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(complexValue != null, "complexValue != null"); // Start the object scope which will represent the entire complex instance jsonWriter.StartObjectScope(); // Write the "__metadata" : { "type": "typename" } // But only if we actually have a typename to write, otherwise we need the __metadata to be omitted entirely string typeName = complexValue.TypeName; // resolve the type name to the resource type; if no type name is specified we will use the // type inferred from metadata ResourceType complexValueType = MetadataUtils.ResolveTypeName(metadata, resourcePropertyType, ref typeName, ResourceTypeKind.ComplexType, isOpenPropertyType); if (typeName != null) { // Write the __metadata object jsonWriter.WriteName(JsonConstants.ODataMetadataName); jsonWriter.StartObjectScope(); // "type": "typename" jsonWriter.WriteName(JsonConstants.ODataMetadataTypeName); jsonWriter.WriteValue(typeName); // End the __metadata jsonWriter.EndObjectScope(); } // Write the properties of the complex value as usual WriteProperties(jsonWriter, metadata, complexValueType, complexValue.Properties, version); // End the object scope which represents the complex instance jsonWriter.EndObjectScope(); }
/// <summary> /// Writes a primitive value. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="value">The value to write.</param> /// <param name="expectedType">The expected resource type of the primitive value.</param> internal static void WritePrimitiveValue(JsonWriter jsonWriter, object value, ResourceType expectedType) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(value != null, "value != null"); if (expectedType != null) { ValidationUtils.ValidateIsExpectedPrimitiveType(value, expectedType); } TypeCode typeCode = Type.GetTypeCode(value.GetType()); switch (typeCode) { case TypeCode.Boolean: jsonWriter.WriteValue((bool)value); break; case TypeCode.Byte: jsonWriter.WriteValue((byte)value); break; case TypeCode.DateTime: jsonWriter.WriteValue((DateTime)value); break; case TypeCode.Decimal: jsonWriter.WriteValue((decimal)value); break; case TypeCode.Double: jsonWriter.WriteValue((double)value); break; case TypeCode.Int16: jsonWriter.WriteValue((Int16)value); break; case TypeCode.Int32: jsonWriter.WriteValue((Int32)value); break; case TypeCode.Int64: jsonWriter.WriteValue((Int64)value); break; case TypeCode.SByte: jsonWriter.WriteValue((sbyte)value); break; case TypeCode.Single: jsonWriter.WriteValue((Single)value); break; case TypeCode.String: jsonWriter.WriteValue((string)value); break; default: { byte[] valueAsByteArray = value as byte[]; if (valueAsByteArray != null) { jsonWriter.WriteValue(Convert.ToBase64String(valueAsByteArray)); break; } if (value is DateTimeOffset) { jsonWriter.WriteValue((DateTimeOffset)value); break; } if (value is Guid) { jsonWriter.WriteValue((Guid)value); break; } if (value is TimeSpan) { jsonWriter.WriteValue((TimeSpan)value); break; } } throw new ODataException(Strings.ODataJsonWriter_UnsupportedValueType(value.GetType().FullName)); } }
/// <summary> /// Write an error message. /// </summary> /// <param name="jsonWriter">The JSON writer to write to.</param> /// <param name="error">The error instance to write.</param> /// <param name="includeDebugInformation">A flag indicating whether error details should be written (in debug mode only) or not.</param> internal static void WriteError(JsonWriter jsonWriter, ODataError error, bool includeDebugInformation) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(error != null, "error != null"); string code, message, messageLanguage; ODataUtilsInternal.GetErrorDetails(error, out code, out message, out messageLanguage); string innerError = includeDebugInformation ? error.InnerError : null; WriteError(jsonWriter, code, message, messageLanguage, innerError); }
/// <summary> /// Write a top-level error message. /// </summary> /// <param name="jsonWriter">The JSON writer to write to.</param> /// <param name="error">The error instance to write.</param> /// <param name="includeDebugInformation">A flag indicating whether error details should be written (in debug mode only) or not.</param> /// <param name="writingResponse">True if the writer is to write a response payload; false if it's to write a request payload.</param> internal static void WriteTopLevelError(JsonWriter jsonWriter, ODataError error, bool includeDebugInformation, bool writingResponse) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(error != null, "error != null"); WriteDataWrapper(jsonWriter, writingResponse, () => WriteError(jsonWriter, error, includeDebugInformation)); }
/// <summary> /// Helper method to write the data wrapper around a JSON payload. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="writingResponse">A flag indicating whether we are writing a response; data wrappers are only added to response messages.</param> /// <param name="payloadWriterAction">The action that writes the actual JSON payload that is being wrapped.</param> internal static void WriteDataWrapper(JsonWriter jsonWriter, bool writingResponse, Action payloadWriterAction) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(payloadWriterAction != null, "payloadWriterAction != null"); if (writingResponse) { // If we're writing a response payload the entire JSON should be wrapped in { "d": } to guard against XSS attacks // it makes the payload a valid JSON but invalid JScript statement. jsonWriter.StartObjectScope(); jsonWriter.WriteDataWrapper(); } payloadWriterAction(); if (writingResponse) { // If we were writing a response payload the entire JSON is wrapped in an object scope, which we need to close here. jsonWriter.EndObjectScope(); } }
/// <summary> /// Writes a set of links (Uris) in response to a $links query; includes optional count and next-page-link information. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="baseUri">The base Uri used for writing.</param> /// <param name="associatedEntityLinks">The set of associated entity links to write out.</param> /// <param name="version">The protocol version used for writing.</param> /// <param name="writingResponse">Flag indicating whether a request or a response is being written.</param> internal static void WriteAssociatedEntityLinks(JsonWriter jsonWriter, Uri baseUri, ODataAssociatedEntityLinks associatedEntityLinks, ODataVersion version, bool writingResponse) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(associatedEntityLinks != null, "associatedEntityLinks != null"); ODataJsonWriterUtils.WriteDataWrapper( jsonWriter, writingResponse, () => WriteAssociatedEntityLinks(jsonWriter, baseUri, associatedEntityLinks, version >= ODataVersion.V2 && writingResponse)); }
/// <summary> /// Writes a single top-level Uri in response to a $links query. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="baseUri">The base Uri used for writing.</param> /// <param name="link">The associated entity link to write out.</param> /// <param name="writingResponse">Flag indicating whether a request or a response is being written.</param> internal static void WriteAssociatedEntityLink(JsonWriter jsonWriter, Uri baseUri, ODataAssociatedEntityLink link, bool writingResponse) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(link != null, "link != null"); ODataJsonWriterUtils.WriteDataWrapper( jsonWriter, writingResponse, () => WriteAssociatedEntityLink(jsonWriter, baseUri, link)); }
/// <summary> /// Write an <see cref="ODataProperty" /> to the given stream. This method creates an /// async buffered stream and writes the property to it. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="property">The property to write.</param> /// <param name="owningType">The type owning the property (or null if no metadata is available).</param> /// <param name="version">The protocol version used for writing.</param> /// <param name="writingResponse">Flag indicating whether a request or a response is being written.</param> internal static void WriteTopLevelProperty( JsonWriter jsonWriter, DataServiceMetadataProviderWrapper metadata, ODataProperty property, ResourceType owningType, ODataVersion version, bool writingResponse) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(property != null, "property != null"); ODataJsonWriterUtils.WriteDataWrapper( jsonWriter, writingResponse, () => { jsonWriter.StartObjectScope(); WriteProperty(jsonWriter, metadata, property, owningType, version); jsonWriter.EndObjectScope(); }); }
/// <summary> /// Writes a service document in JSON format. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="defaultWorkspace">The default workspace to write in the service document.</param> internal static void WriteServiceDocument( JsonWriter jsonWriter, DataServiceMetadataProviderWrapper metadata, ODataWorkspace defaultWorkspace) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(defaultWorkspace != null, "defaultWorkspace != null"); IEnumerable<ODataResourceCollectionInfo> collections = ValidationUtils.ValidateWorkspace(metadata == null ? null : metadata.ResourceSets, defaultWorkspace); Debug.Assert(collections != null, "collections != null"); WriteDataWrapper( jsonWriter, true, () => { // "{" jsonWriter.StartObjectScope(); // "EntitySets": jsonWriter.WriteName(JsonConstants.ODataServiceDocumentEntitySetsName); // "[" jsonWriter.StartArrayScope(); foreach (ODataResourceCollectionInfo collectionInfo in collections) { ValidationUtils.ValidateResourceCollectionInfo(collectionInfo); // <collection name> jsonWriter.WriteValue(collectionInfo.Name); } // "]" jsonWriter.EndArrayScope(); // "}" jsonWriter.EndObjectScope(); }); }
/// <summary> /// Creates a new <see cref="AsyncWriter"/> based on a JSON writer. /// </summary> /// <param name="asyncBufferedStream">The async buffered stream to use.</param> /// <param name="textWriter">The text writer backing the <see cref="jsonWriter"/>.</param> /// <param name="jsonWriter">The JSON writer to write to.</param> internal AsyncWriter(AsyncBufferedStream asyncBufferedStream, TextWriter textWriter, JsonWriter jsonWriter) { Debug.Assert(asyncBufferedStream != null, "asyncBufferedStream != null"); Debug.Assert(textWriter != null, "textWriter != null"); Debug.Assert(jsonWriter != null, "jsonWriter != null"); this.asyncBufferedStream = asyncBufferedStream; this.textWriter = textWriter; this.jsonWriter = jsonWriter; }
/// <summary> /// Write an error message. /// </summary> /// <param name="jsonWriter">The JSON writer to write to.</param> /// <param name="code">The code of the error.</param> /// <param name="message">The message of the error.</param> /// <param name="messageLanguage">The language of the message.</param> /// <param name="innerError">Inner error details that will be included in debug mode (if present).</param> private static void WriteError(JsonWriter jsonWriter, string code, string message, string messageLanguage, string innerError) { Debug.Assert(jsonWriter != null, "writer != null"); Debug.Assert(code != null, "code != null"); Debug.Assert(message != null, "message != null"); Debug.Assert(messageLanguage != null, "messageLanguage != null"); // { "error": { jsonWriter.StartObjectScope(); jsonWriter.WriteName(JsonConstants.ODataErrorName); jsonWriter.StartObjectScope(); // "code": "<code>" jsonWriter.WriteName(JsonConstants.ODataErrorCodeName); jsonWriter.WriteValue(code); // "message": { jsonWriter.WriteName(JsonConstants.ODataErrorMessageName); jsonWriter.StartObjectScope(); // "lang": "<messageLanguage>" jsonWriter.WriteName(JsonConstants.ODataErrorMessageLanguageName); jsonWriter.WriteValue(messageLanguage); // "value": "<message>" jsonWriter.WriteName(JsonConstants.ODataErrorMessageValueName); jsonWriter.WriteValue(message); // } jsonWriter.EndObjectScope(); if (!string.IsNullOrEmpty(innerError)) { // "innererror": { jsonWriter.WriteName(JsonConstants.ODataErrorInnerErrorName); jsonWriter.StartObjectScope(); // Design 29: JSON error format for inner error - the inner error format is unclear, for now choosing // to use the value property. // "value": "<innerError>" jsonWriter.WriteName(JsonConstants.ODataErrorMessageValueName); jsonWriter.WriteValue(innerError); // } jsonWriter.EndObjectScope(); } // } } jsonWriter.EndObjectScope(); jsonWriter.EndObjectScope(); }
private AsyncWriter WriteTopLevelContent( Stream stream, Action<XmlWriter> writeAtomAction, Action<JsonWriter> writeJsonAction, Func<object, string> invalidContentTypeErrorMessageFunction, InternalErrorCodes internalErrorCode) { Debug.Assert(this.writerPayloadKind != ODataPayloadKind.Unsupported, "Expected payload kind, format and encoding to be set by now."); AsyncBufferedStream asyncBufferedStream = new AsyncBufferedStream(stream); switch (this.format) { case ODataFormat.Json: StreamWriter textWriter = new StreamWriter(asyncBufferedStream, this.encoding); JsonWriter jsonWriter = new JsonWriter(textWriter, this.settings.Indent); writeJsonAction(jsonWriter); return new AsyncWriter(asyncBufferedStream, textWriter, jsonWriter); case ODataFormat.Atom: XmlWriter xmlWriter = ODataAtomWriterUtils.CreateXmlWriter(asyncBufferedStream, this.settings, this.encoding); writeAtomAction(xmlWriter); return new AsyncWriter(asyncBufferedStream, xmlWriter); case ODataFormat.Default: Debug.Assert(false, "Should never get here as content-type negotiation should not return Default format for top level content."); string contentType = this.message.GetHeader(ODataHttpHeaders.ContentType); throw new ODataException(invalidContentTypeErrorMessageFunction(contentType)); default: throw new ODataException(Strings.General_InternalError(internalErrorCode)); } }
/// <summary> /// Flush and close the writer. /// </summary> /// <param name="discardBufferedData">If true discard any buffered data before closing the writer.</param> /// <remarks>This is only called during disposal of the writer.</remarks> protected override void FlushAndCloseWriter(bool discardBufferedData) { try { // Flush the JSON writer so that we guarantee that there's no data buffered in the JSON writer; // the underlying stream verifies that no data is still buffered when disposed below. this.jsonWriter.Flush(); if (discardBufferedData) { this.outputStream.Clear(); } // The text writer will also dispose the this.outputStream since it owns that stream // which in turn will dispose the real output stream underneath it. this.textWriter.Dispose(); } finally { this.jsonWriter = null; this.textWriter = null; this.outputStream = null; } }