/// <summary> /// Writes the metadata properties for a resource which can only occur at the end. /// </summary> /// <param name="resourceState">The resource state for which to write the metadata properties.</param> /// <param name="duplicatePropertyNameChecker">The DuplicatePropertyNameChecker to use.</param> internal void WriteResourceEndMetadataProperties(IODataJsonLightWriterResourceState resourceState, IDuplicatePropertyNameChecker duplicatePropertyNameChecker) { Debug.Assert(resourceState != null, "resourceState != null"); ODataResourceBase resource = resourceState.Resource; var navigationLinkInfo = resource.MetadataBuilder.GetNextUnprocessedNavigationLink(); while (navigationLinkInfo != null) { Debug.Assert(resource.MetadataBuilder != null, "resource.MetadataBuilder != null"); navigationLinkInfo.NestedResourceInfo.MetadataBuilder = resource.MetadataBuilder; this.WriteNavigationLinkMetadata(navigationLinkInfo.NestedResourceInfo, duplicatePropertyNameChecker); navigationLinkInfo = resource.MetadataBuilder.GetNextUnprocessedNavigationLink(); } // write "odata.actions" metadata IEnumerable <ODataAction> actions = resource.Actions; if (actions != null && actions.Any()) { this.WriteOperations(actions.Cast <ODataOperation>(), /*isAction*/ true); } // write "odata.functions" metadata IEnumerable <ODataFunction> functions = resource.Functions; if (functions != null && functions.Any()) { this.WriteOperations(functions.Cast <ODataOperation>(), /*isAction*/ false); } }
/// <summary> /// Writes the metadata properties for a resource which can only occur at the start. /// </summary> /// <param name="resourceState">The resource state for which to write the metadata properties.</param> internal void WriteResourceStartMetadataProperties(IODataJsonLightWriterResourceState resourceState) { Debug.Assert(resourceState != null, "resourceState != null"); ODataResourceBase resource = resourceState.Resource; // expectedResourceTypeName : if expected is of base type. but the resource real type is derived, // we need to set the resource type name. // Writing response: expected type info can be identical with context uri info. // Writing request: contextUri may not be provided, we always use the type from metadata info. // From model: if the resource can be found in model. // From serializationInfo: if user set the serializationInfo for the resource. string expectedResourceTypeName = null; if (this.WritingResponse) { expectedResourceTypeName = resourceState.GetOrCreateTypeContext(this.WritingResponse).ExpectedResourceTypeName; } else { if (resourceState.ResourceTypeFromMetadata == null) { expectedResourceTypeName = resourceState.SerializationInfo == null ? null : resourceState.SerializationInfo.ExpectedTypeName; } else { expectedResourceTypeName = resourceState.ResourceTypeFromMetadata.FullTypeName(); } } // Write the "@odata.type": "typename" string typeName = this.JsonLightOutputContext.TypeNameOracle.GetResourceTypeNameForWriting( expectedResourceTypeName, resource, resourceState.IsUndeclared); if (typeName != null && !string.Equals(typeName, ODataConstants.ContextUriFragmentUntyped, StringComparison.Ordinal)) { this.ODataAnnotationWriter.WriteODataTypeInstanceAnnotation(typeName); } // Write the "@odata.id": "Entity Id" Uri id; if (resource.MetadataBuilder.TryGetIdForSerialization(out id)) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataId); if (id != null && !resource.HasNonComputedId) { id = this.MetadataDocumentBaseUri.MakeRelativeUri(id); } this.JsonWriter.WriteValue(id == null ? null : this.UriToString(id)); } // Write the "@odata.etag": "ETag value" string etag = resource.ETag; if (etag != null) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataETag); this.JsonWriter.WriteValue(etag); } }
/// <summary> /// Writes the metadata properties for a resource which can occur both at the start or at the end. /// </summary> /// <param name="resourceState">The resource state for which to write the metadata properties.</param> /// <remarks> /// This method will only write properties which were not written yet. /// </remarks> internal void WriteResourceMetadataProperties(IODataJsonLightWriterResourceState resourceState) { Debug.Assert(resourceState != null, "resourceState != null"); ODataResourceBase resource = resourceState.Resource; // Write the "@odata.editLink": "edit-link-uri" Uri editLinkUriValue = resource.EditLink; if (editLinkUriValue != null && !resourceState.EditLinkWritten) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataEditLink); this.JsonWriter.WriteValue(this.UriToString( resource.HasNonComputedEditLink || !editLinkUriValue.IsAbsoluteUri ? editLinkUriValue : this.MetadataDocumentBaseUri.MakeRelativeUri(editLinkUriValue))); resourceState.EditLinkWritten = true; } // Write the "@odata.readLink": "read-link-uri". // If readlink is identical to editlink, don't write readlink. Uri readLinkUriValue = resource.ReadLink; if (readLinkUriValue != null && readLinkUriValue != editLinkUriValue && !resourceState.ReadLinkWritten) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataReadLink); this.JsonWriter.WriteValue(this.UriToString( resource.HasNonComputedReadLink ? readLinkUriValue : this.MetadataDocumentBaseUri.MakeRelativeUri(readLinkUriValue))); resourceState.ReadLinkWritten = true; } // Write MLE metadata ODataStreamReferenceValue mediaResource = resource.MediaResource; if (mediaResource != null) { // Write the "@odata.mediaEditLink": "edit-link-uri" Uri mediaEditLinkUriValue = mediaResource.EditLink; if (mediaEditLinkUriValue != null && !resourceState.MediaEditLinkWritten) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataMediaEditLink); this.JsonWriter.WriteValue(this.UriToString( mediaResource.HasNonComputedEditLink ? mediaEditLinkUriValue : this.MetadataDocumentBaseUri.MakeRelativeUri(mediaEditLinkUriValue))); resourceState.MediaEditLinkWritten = true; } // Write the "@odata.mediaReadLink": "read-link-uri" // If mediaReadLink is identical to mediaEditLink, don't write readlink. Uri mediaReadLinkUriValue = mediaResource.ReadLink; if (mediaReadLinkUriValue != null && mediaReadLinkUriValue != mediaEditLinkUriValue && !resourceState.MediaReadLinkWritten) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataMediaReadLink); this.JsonWriter.WriteValue(this.UriToString( mediaResource.HasNonComputedReadLink ? mediaReadLinkUriValue : this.MetadataDocumentBaseUri.MakeRelativeUri(mediaReadLinkUriValue))); resourceState.MediaReadLinkWritten = true; } // Write the "@odata.mediaContentType": "content/type" string mediaContentType = mediaResource.ContentType; if (mediaContentType != null && !resourceState.MediaContentTypeWritten) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataMediaContentType); this.JsonWriter.WriteValue(mediaContentType); resourceState.MediaContentTypeWritten = true; } // Write the "@odata.mediaEtag": "ETAG" string mediaETag = mediaResource.ETag; if (mediaETag != null && !resourceState.MediaETagWritten) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataMediaETag); this.JsonWriter.WriteValue(mediaETag); resourceState.MediaETagWritten = true; } } // TODO: actions // TODO: functions // TODO: association links }
/// <summary> /// Writes the metadata properties for a resource which can only occur at the start. /// </summary> /// <param name="resourceState">The resource state for which to write the metadata properties.</param> internal void WriteResourceStartMetadataProperties(IODataJsonLightWriterResourceState resourceState) { Debug.Assert(resourceState != null, "resourceState != null"); ODataResource resource = resourceState.Resource; // expectedResourceTypeName : if expected is of base type. but the resource real type is derived, // we need to set the resource type name. // Writing response: expected type info can be identical with context uri info. // Writing request: contextUri may not be provided, we always use the type from metadata info. // From model: if the resource can be found in model. // From serializationInfo: if user set the serializationInfo for the resource. string expectedResourceTypeName = null; if (this.WritingResponse) { expectedResourceTypeName = resourceState.GetOrCreateTypeContext(this.WritingResponse).ExpectedResourceTypeName; } else { if (resourceState.ResourceTypeFromMetadata == null) { expectedResourceTypeName = resourceState.SerializationInfo == null ? null : resourceState.SerializationInfo.ExpectedTypeName; } else { expectedResourceTypeName = resourceState.ResourceTypeFromMetadata.FullTypeName(); } } // Write the "@odata.type": "typename" string typeName = this.JsonLightOutputContext.TypeNameOracle.GetResourceTypeNameForWriting( expectedResourceTypeName, resource, resourceState.IsUndeclared); if (typeName != null) { this.ODataAnnotationWriter.WriteODataTypeInstanceAnnotation(typeName); } // uncomment the below if decide to expose OData information via .InstanceAnnotations // else // { // // close path for roundtrip : // // write it to the wire if @odata.type is ever read from payload into Resource.InstanceAnnotations. // ODataInstanceAnnotation odataTypeAnnotation = resource.InstanceAnnotations.FirstOrDefault( // s => string.Equals(ODataAnnotationNames.ODataType, s.Name, StringComparison.OrdinalIgnoreCase)); // if (odataTypeAnnotation != null) // { // string rawTypeName = (string)odataTypeAnnotation.Value.FromODataValue(); // this.ODataAnnotationWriter.WriteODataTypeInstanceAnnotation(rawTypeName, writeRawValue: true); // } // } // Write the "@odata.id": "Entity Id" Uri id; if (resource.MetadataBuilder.TryGetIdForSerialization(out id)) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataId); if (id != null && !resource.HasNonComputedId) { id = this.MetadataDocumentBaseUri.MakeRelativeUri(id); } this.JsonWriter.WriteValue(id == null ? null : this.UriToString(id)); } // Write the "@odata.etag": "ETag value" string etag = resource.ETag; if (etag != null) { this.ODataAnnotationWriter.WriteInstanceAnnotationName(ODataAnnotationNames.ODataETag); this.JsonWriter.WriteValue(etag); } }